Как реализовать правильный шаблон хранилища в .NET - PullRequest
0 голосов
/ 12 октября 2018

В этой статье объясняется, как создать универсальный класс HttpClient со всеми основными операциями CRUD.Затем он создает репозиторий для конкретного типа для конкретного объекта POCO (Called Member).

Что я не понимаю, так это необходимость в классе MemberReposity, который возвращает именно то, что класс GenericHttpClient должен вернуть для определенного типа?Разве я не могу просто переименовать GenericHttpClient в GenericReposity, а затем использовать его для всех моих операций CRUD для объектов POCO?Другими словами, зачем мне нужен уникальный репозиторий для каждого объекта, если все они требуют только базовых операций CRUD?

Я мог бы просто создать их экземпляр в своей форме следующим образом:

private GenericReposity<Customer, int> _customerClient = new GenericReposity<Customer, string>(url, "api/Customers/");

изатем получите клиента следующим образом:

_customerClient.GetAsync(5);

Неужели я здесь упускаю точку?


ОБНОВЛЕНИЕ

После прочтения об Анти-Шаблон Я разработал базовый интерфейс репозитория следующим образом:

internal interface IGenericRepository<T, in TResourceIdentifier>
{
    Task<IEnumerable<T>> GetManyAsync();
    Task<T> GetAsync(TResourceIdentifier id);
    Task PutAsync(T model);
    Task<T> PostAsync(T model);
    Task DeleteAsync(TResourceIdentifier id);
}

Затем я реализовал его:

public class GenericRepository<T, TResourceIdentifier> : IDisposable, IGenericRepository<T, TResourceIdentifier> 
    where T : class
{
    private bool _disposed;
    protected HttpClientHelper<T, TResourceIdentifier> Client;

    protected GenericRepository(string addressSuffix)
    {
        Client = new HttpClientHelper<T, TResourceIdentifier>(Properties.Settings.Url, addressSuffix);
    }

    public async Task<IEnumerable<T>> GetManyAsync()
    {
        return await Client.GetManyAsync();
    }

    // All other CRUD methods and dispose
}

Затем я создал собственный интерфейс репозитория для каждой из моих сущностей.Например:

internal interface IOrderRepository : IGenericRepository<Order, int>
{
    Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition );

}

И, наконец, я реализовал собственный репозиторий:

public class OrderRepository : GenericRepository<Order, int>, IOrderRepository
{
    public OrderRepository(string addressSuffix) : base(addressSuffix)
    {
    }

    public async Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition)
    {
        //get all the orders (GetManyAsync()) and then returns the ones meeting the condition
    }
}

Таким образом, я могу получить все простые операции CRUD без необходимости реализовывать их по одной для каждогосущность, а также любые пользовательские.Это правильный подход?Или это считается анти-паттерном?

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Ваш новый подход (после обновления) выглядит великолепно.

С этим вы обойдете все недостатки универсального репозитория;все еще пользуясь преимуществом повторного использования кода из базового универсального репозитория.

Ничего страшного, но рассмотрите возможность применения всех методов в базовом репозитории protected, чтобы они были доступны только в конкретном репозитории.Конечно, этим предложением можно пренебречь, если все конкретные хранилища реализуют этот метод.

0 голосов
/ 12 октября 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...