Правильная реализация шаблона UnitOfWork и Repository в Entity Framework

Я пытаюсь понять, как правильно реализовать шаблон UoW и Repository с Entity Framework. Я видел много постов против этого, но это все еще кажется правильным путем.

Я пытаюсь сделать это по этому Сообщение блога. Последнее, что я пытаюсь понять, - это как внедрить репозитории в UoW, но таким способом, который позволяет мне делать это по требованию. Количество репозиториев может вырасти, как и конструктор. Более того, создание экземпляров всех репозиториев для операции, которая может потребовать только 1 или 2, кажется пустой тратой ресурсов.

Как мне это сделать, чтобы я мог довольно легко писать модульные тесты?

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

private IGenericRepository<Blog> _blogRepository;
private IGenericRepository<Post> _postRepository;
public UnitOfWork(BloggingContext bloggingContext)
{
    _bloggingContext = bloggingContext;
}

public IGenericRepository<Blog> BlogRepository
{
    get
    {
        return _blogRepository = _blogRepository ?? new GenericRepository<Blog>(_bloggingContext);
    }
}

Однако такой подход создает много шума в коде, потому что, когда у меня будет 50 репозиториев, мне понадобится 50 реквизитов.

Мне кажется, что вы хотите достичь не UoW, а набора UoW, реализованных в одном классе, в зависимости от данной операции. Сначала я хотел бы спросить, почему вы хотите это сделать. После этого, да, вы можете просто использовать ленивое построение, создав востребованное репо. Если вы хотите избежать большого количества реквизитов, используйте общий метод типа T и сохраните репозитории в словаре или cncurrent словаре, индексированном T

Sentinel 22.04.2018 13:42

@Sentinel Я хотел создать стандартный шаблон UoW + Repository, а не набор UoW. Все репозитории в одном UoW должны совместно использовать DbContext. Вторая часть о методе Т. - отличное предложение. Я нашел этот stackoverflow.com/questions/16064902/…, и он похож на то, что вы предложили с помощью dict.

catdoanything33 22.04.2018 14:52

они также упоминают Lazy <T>, который может вам помочь.

Sentinel 22.04.2018 15:24

@Sentinel Ну, моя последняя проблема заключается в том, что с подходом dict мне пришлось бы делать некрасивое приведение при каждом использовании: / Есть предложения? редактировать. Я мог бы использовать фабрику в UoW, чтобы получить все репозитории по запросу. Это должно хорошо работать?

catdoanything33 22.04.2018 16:24

@ catdoanyrhing33 Не уверен, почему вам нужно использовать приведение везде, просто верните T в общем методе get <T>. Итак, у вас будет var X = get <myrepo> (); с макушки, которая не требует гипсовой повязки, верно?

Sentinel 22.04.2018 19:46

обход фабрик тоже работает. Ленивый экземпляр, принимающий универсальный параметр, можно рассматривать как тип фабрики.

Sentinel 22.04.2018 19:48

У меня ограниченный опыт работы с контейнерами IoC. По какой-то причине большинство проектов, над которыми я работал, их избегали. IMO IoC иногда делает код менее читаемым. Я думаю, что если у вас есть достаточно веские основания для перехода в какую-то заводскую или заводскую конфигурацию, продолжайте. Иногда беспокойство об антипаттернах может быть контрпродуктивным.

Sentinel 23.04.2018 07:22

Суть фабрики в том, что вы можете указать, какой тип репо использовать, например EF, in-memory или другие реализации backend dataaccezs. Вообще это перебор. БД, как правило, никогда не меняются, что означает, что вы не собираетесь переключаться с EF на Azure NoSQL и не хотите программировать для этого сценария.

Sentinel 23.04.2018 07:31

Молодцы с реализацией.

Sentinel 23.04.2018 07:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
679
1

Ответы 1

Возможно, вы захотите объединить описанный подход (который мне нравится) с общим подходом к репозиторию, описанным здесь https://cpratt.co/truly-generic-repository/ При правильной реализации шаблона UoW из сообщения в блоге, на которое вы ссылаетесь, вам не понадобится ничего, кроме IReadOnlyRepository из статьи - он предоставит все, что вам нужно для репозитория.

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