Как убрать избыточность кода в репозиториях - PullRequest
1 голос
/ 10 апреля 2020

В настоящее время у меня есть 2 таблицы в моей базе данных. Питание и столы (это приложение для управления рестораном). Я создал интерфейсы репозиториев и их реализацию для обеих таблиц (авторизованный пользователь должен иметь возможность добавлять / удалять / обновлять данные о блюдах и таблицах, когда, например, в меню появляется новая еда). Проблема в том, что оба моих интерфейса имеют в основном один и тот же метод, который, как я полагаю, вызывает избыточность кода. Это мои интерфейсы:

public interface IMealsRepository
{
    IEnumerable<Meal> FindAll();
    Meal FindById(int id);
    Meal FindByName(string mealName);
    Meal AddMeal(MealDTO newMeal);
    void RemoveMeal(int id);
    Meal UpdateMeal(Meal meal);
}

public interface ITablesRepository
{
    IEnumerable<Table> FindAll();
    Table FindById(int id);
    Table AddTable(Table newTable);
    void RemoveTable(int id);
    Table UpdateTable(Table table);
}

Я пытался создать базовый интерфейс репозитория с общими методами FindAll, FindById, Add, Remove, Update, но столкнулся с проблемой, которую я беру и возвращаю различные типы, например для метода Add я либо возвращаю объект Table или Meal в зависимости от интерфейса. Я попытался go с объектным подходом:

public interface IRepository
{
    IEnumerable<object> FindAll();
    object FindById(int id);
    object Add(object newObject);
    void Remove(int id);
    object Update(object updatedObject);
}

Тогда я бы просто IMealsRepository: IRepository и ITablesRepository: IRepository и добавил дополнительные методы, уникальные для этих хранилищ, например, поиск еды по имени. Мой интерфейс питания будет выглядеть так:

public interface IMealsRepository : IRepository
{
    Meal FindByName(string mealName);
}

У меня также есть Службы для тех репозиториев, которые являются единственными, которые могут получить доступ к репозиториям и возвращать эти конкретные типы объектов, используя методы репозиториев. Это хороший подход или я слишком углубляюсь в этот проект в отношении интерфейсов моих репозиториев?

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Вы можете перейти по этой ссылке для реализации универсального / базового репозитория (если вы не используете Entity Framework / SQL, это все еще допустимо).

Кроме Base / Generi c шаблон репозитория, вам нужно учесть несколько вещей

  1. Использовать шаблон UnitOfWork при выполнении операции в нескольких репозиториях для поддержки транзакции.

  2. Не создавайте репозиторий для каждого объекта таблицы / домена. Создайте репозиторий только для агрегированного объекта (например, в контексте электронной торговли: Order не для OrderDetail).

  3. Не создавать таблицу / домен-специфицированный c репозиторий Если вам не нужно. Если вы выполняете простую операцию CRUD и все типы операций уже доступны в моем базовом репозитории, то вам не требуется таблица c репозиторий

    publi c класс IBaseRepository imageRepository;

    public AdvertisementService(
        IBaseRepository<AdvertisementImage> imageRepository)
    {
    
        this.imageRepository = imageRepository;
    }
    

Startup.cs

builder.Services.AddScoped<IBaseRepository<AdvertisementImage>, BaseRepository<AdvertisementImage>>();

В приведенном выше примере я не создавал `AdvertisingImage ' хранилище.

1 голос
/ 10 апреля 2020

Этот тип проблемы может быть решен с помощью. NET Generics. Обобщения позволяют создавать классы, такие как RepositoryBase<T>, и интерфейсы, такие как IRepository<T>

. "T" - это тип объекта, который вы указываете в наследующем классе или реализующем интерфейсе.

Использование обобщенных элементов , вы можете создать интерфейс, подобный этому:

public interface IRepository<T>
{
    IEnumerable<T> FindAll();
    T FindById(int id);
    T Add(T newObject);
    void Remove(int id);
    T Update(T updatedObject);
}

Или базовый класс, подобный этому:

public abstract class RepositoryBase<T, TDto> : IRepository<T>
{
    protected IEnumerable<T> FindAll() { // your implementation logic}
    protected T FindById(int id) { // your implementation logic
    protected T FindByName(string mealName) { // your implementation logic
    protected T AddMeal(TDto newMeal) { // your implementation logic
    protected void RemoveMeal(int id) { // your implementation logic
    protected T UpdateMeal(Meal meal) { // your implementation logic
}

В inte rnet имеется много информации о дженериках, но я Я уверен, что в этом сценарии вы хотите использовать Generics.

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