Как преобразовать метод в реализацию базового класса?

Я уже реализовал свой класс репозитория, но мне интересно, как я могу преобразовать его методы в базовый класс, который может быть расширен различными типами репозитория.

Я начал с создания базового класса Repository ниже, но не уверен, насколько абстрактным должен быть каждый метод. Кроме того, как я должен заменить тип модели с общим заполнителем.

В этом примере абстрактные методы содержат только определение метода, а не реализацию:

public abstract Array sort(Array arr);

Кто-нибудь может посоветовать, как реорганизовать методы для дженериков?

Я начал с создания базового абстрактного класса Repository, но застрял при замене методов на общие типы и общие параметры.

Пример ниже Delete() который является специфическим для CustomerModel. Это должно быть универсальным для более легкого повторного использования класса:

public abstract class BaseRepository
{
    public async Task DeleteCustomer(CustomerModel customer)
    {
        var collection = StartConnection();
        var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
        var result = await collection.DeleteOneAsync(filter);
        customers.Remove(customer);
    }
}

Так, например, это полный класс CustomerRepository, который содержит операции CRUD для моей удаленной базы данных. Все методы специфичны для CustomerModel, что затрудняет повторное использование:

public class CustomerRepository : ICustomerRepository
{
    private static List<CustomerModel> customers = new List<CustomerModel>();

    static CustomerRepository()
    {
    }

    private CustomerRepository()
    {

    }

    public static CustomerRepository Instance
    {
        get
        {
            return instance;
        }
    }

    public CustomerModel GetACustomer()
    {
        if (customers == null)
            LoadCustomers();
        return customers.FirstOrDefault();
    }

    public List<CustomerModel> GetCustomers()
    {
        if (customers.Count == 0)
            LoadCustomers();
        return customers;
    }

    public CustomerModel GetCustomerById(ObjectId id)
    {
        if (customers == null)
            LoadCustomers();
        return customers.Where(c => c.Id == id).FirstOrDefault();
    }

    public CustomerModel GetCustomerByEmail(string email)
    {
        if (customers == null)
            LoadCustomers();
        return customers.Where(c => c.Email == email).FirstOrDefault();
    }

    public async Task DeleteCustomer(CustomerModel customer)
    {
        var collection = StartConnection();
        var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
        var result = await collection.DeleteOneAsync(filter);
        customers.Remove(customer);
    }

    public async Task AddCustomer(CustomerModel customer)
    {
        var collection = StartConnection();
        await collection.InsertOneAsync(customer);
        customers.Add(customer);
    }

    public async Task UpdateCustomer(CustomerModel customer)
    {          
        var collection = StartConnection();
        var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);

        collection.Find(filter).ToString();
        var result = await collection.ReplaceOneAsync(filter, customer, new UpdateOptions { IsUpsert = true });

        var index = customers.FindIndex(a => a.Id == customer.Id);
        customers[index] = customer;
    }

    private void LoadCustomers()
    {
        var collection = StartConnection();

        try
        {
            customers = collection.Find(new BsonDocument()).ToListAsync().GetAwaiter().GetResult();
        }
        catch (MongoException ex)
        {
            //Log exception here:
            MessageBox.Show("A connection error occurred: " + ex.Message, "Connection Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
        }
    }

    private static IMongoCollection<CustomerModel> StartConnection()
    {
        var client = new MongoClient(connectionString);
        var database = client.GetDatabase("orders");
        //Get a handle on the customers collection:
        var collection = database.GetCollection<CustomerModel>("customers");
        return collection;
    }
}

1 ответ

Решение

Не создавайте базовый класс, содержащий методы, специфичные для сущностей. Сделайте базу родовой с самого начала.

public class Repository<T> where T : new()
{
    public async Task<T> GetAsync(object key)
    {}

    public async Task DeleteAsync(T t)
    {}
}

Добавьте любой уровень абстракции, который вам нравится. Если вы используете, например, какой-то ORM в своем репо, этого может быть достаточно.


Вы не можете изменить имена методов в наследуемых классах. И более просто использовать репо, если у всех одинаковые методы для операций.

Если вы можете использовать базу как есть, то только Type изменения параметров. Таким образом, вы бы, например, создать экземпляр Repository<Customer> в вашем коде.

Если логика отличается между сущностями, то, например, CustomerRepository : Repository<Customer> и поставить логику там. Также пометьте базу как абстрактную, а методы абстрактную / виртуальную.

Другие вопросы по тегам