2013-02-12 3 views
0

У нас в настоящее время относительно устаревшая база кода с использованием EntitySpaces (не имеет особого значения, но это ORM, что было приятно использовать в те дни , но с моим недавним опытом EntityFramework это уже не так много), как ORM для прямого доступа к базе данных. Теперь я столкнулся с необходимостью изменить многие части приложения, которые в настоящее время полагаются непосредственно на объекты EntitySpaces. Это нехорошо, но так оно и есть сейчас. Моя общая идея - представить слой, который вводит нейтральные объекты, сохраняющие несовместимые объекты, записывая какой-то интерфейс репозитория для получения, обновления и т. Д. Этих объектов и записи (первой) реализации, которая все еще использует EntitySpaces. Затем я мог бы реорганизовать все те классы и компоненты, которые в настоящее время используют EntitySpaces напрямую. Это, я надеюсь, позволит мне изменить реализацию репозитория позже, чтобы использовать веб-сервис или EntityFramework.Рефакторинг DAL с использованием DI, возможность изменения DAL позже

Вот мои вопросы/ненадежность:

Вообще, я хочу иметь один объект хранилища сидит где-то или лучше обеспечивают компоненты завода, который возвращает (конкретный) репозиторий? Возможно, я мог бы даже разделить репозиторий на разные интерфейсы для разных видов объектов, что приведет к некоторым 20-истным интерфейсам, которые я предполагаю.

Допустим, у меня есть компоненты пользовательского интерфейса, которые теперь выполняют множество операций с базой данных. Если я переписал их для работы с репозиторием, лучше ли «предоставить» этим компонентам объект репозитория или переписать эти компоненты пользовательского интерфейса так, как им даже не нужно знать, что где-то есть репозиторий? Представьте, что есть диалоговое окно, которое позволяет загружать Part из базы данных, изменять его и отправлять обратно. Это можно рассматривать как своего рода интерфейс PartEditor, который может быть просто вызван обратными вызовами для использования, когда пользователь нажимает на кнопку . Обновление или Удалить.

Вы бы даже использовали рамки DI для этой задачи? Приложение относительно большое, около 800 тыс. Локусов, я думаю, без повторных системных библиотек. Альтернативой было бы просто скрыть конкретные классы от всех компонентов, не используя рамки DI, чтобы избежать появления новых проблем. Для компонентов, использующих мои новые абстракции, это не должно меняться, так как эти компоненты должны быть написаны так, что им не нужно знать используемую инфраструктуру DI, правильно?

Я знаю, что это довольно абстрактно и, может быть, трудно ответить, но я надеюсь, что у других есть некоторый опыт в этой задаче. Я благодарен за любые указатели. Что касается вопроса о том, какие рамки DI использовать, im полностью открывается.

ответ

2

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

Я бы создал один репозиторий для каждого заполнителя. Это упрощает обслуживание и тестирование кода.

Допустим, у меня есть компоненты пользовательского интерфейса, которые теперь выполняют множество операций с базой данных. Если я переписал их для работы с репозиторием, лучше ли «предоставить» этим компонентам объект репозитория или переписать эти компоненты пользовательского интерфейса так, как им даже не нужно знать, что где-то есть репозиторий? Представьте, что есть диалоговое окно, которое позволяет загружать часть из базы данных, изменять ее и отправлять обратно. Это можно рассматривать как своего рода интерфейс PartEditor, который может быть просто вызван обратными вызовами для использования, когда пользователь нажимает кнопку «Обновить» или «Удалить».

Для этого вы должны использовать шаблон хранилища. Вы можете переключиться на DataAdapter в репозитории для пакетных методов (если вы считаете, что производительность EF слишком бедна для этих сценариев). Это то, что так хорошо с абстракциями. Вы можете соответствовать реализации после того, что вам нужно, не затрагивая остальную часть кода.

Вы бы использовали рамки DI для этой задачи? Приложение относительно большое, около 800 тыс. Локусов, я думаю, без повторных системных библиотек. Альтернативой было бы просто скрыть конкретные классы от всех компонентов, не используя рамки DI, чтобы избежать появления новых проблем. Для компонентов, использующих мои новые абстракции, это не должно меняться, так как эти компоненты должны быть написаны так, что им не нужно знать используемую инфраструктуру DI, правильно?

Я использую рамки DI при работе с базой данных. Это облегчает передачу всем репозиториям одного и того же соединения и транзакции (без эскалации на распределенные транзакции).

Вы можете прочитать о реализации, что я сделал для EF здесь: http://blog.gauffin.org/2013/01/repository-pattern-done-right/

+0

Особая благодарность за ссылку, я рассмотрю ее. – Jobo

1

В общем, я хочу иметь один объект хранилища, сидя вокруг где-то или лучше, чтобы обеспечить компоненты а фабрика, на которой возвращает (конкретный) репозиторий? Возможно, я мог бы даже разделить репозиторий на разные интерфейсы для разных видов объектов, , которые приведут к некоторым 20-истным интерфейсам, которые, как я думаю.

Я хотел бы предложить вам создать общий репозиторий, который скрывает перевод домена к-данных (либо с помощью OR/M или любой другой), а затем создать его экземпляр с помощью инверсию управления:

// The factory hides who's the actual 
// repository implementation. In your case, it could be 
// EntityFrameworkRepository<T> or EFGenericRepository<T> 
GenericRepository<Order> orderRepo = RepositoryFactory.Create<Order>(); 

хранилище может иметь эти методы:

  • Добавить.
  • GetById.
  • Удалить.
  • GetByCriteria ([дерево выражений]) (например, queryable => queryable.Where(...)). Этот метод может принимать входной аргумент как Expression<Func<IQueryable<T>, IQueryable<T>>>. Entity Framework и NHibernate позволят вам реализовать его таким образом.

Используя этот подход - общий репозиторий - вы избегаете, что 20, 30 хранилищ и, кроме того, у Вас есть реализация базового хранилища, реализующая или конкретные задачи/M для того, чтобы избежать распространений конкретных зависимостей по вашей базе коды !

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

Пользовательский интерфейс не должен знать о репозиториях. Это должен быть бизнес-домен, посредник чего-то вроде UI и репозитория.

Вы бы даже использовали рамки DI для этой задачи? Приложение является относительно большим, около 800 тыс. Мест, которые, как я думаю, без повторных системных библиотек . Альтернативой было бы просто скрыть конкретные классы от всех компонентов без использования каркаса DI, чтобы избежать появления новых проблем. Для компонентов, использующих мои новые абстракции , это не должно меняться, так как эти компоненты должны быть , написанные таким образом, что им не нужно знать используемые рамки DI, ?

Да, используйте каркас DI/IoC. Не избегайте неизбежных и не изобретайте колеса, что является серьезной проблемой, чем использование сторонних библиотек! Я хотел бы предложить вам Castle Windsor, потому что его зрелость, надежность и функциональность.

+0

*** 1. *** Какая польза от такого репозитория будет отдаваться с использованием 'IDbContext' или' ISession' напрямую? *** 2. *** Почему вы говорите: «Пользовательский интерфейс не должен знать о хранилищах. Это должна быть модель. Это не имеет никакого смысла, если у вас нет анемичных доменных моделей. – jgauffin

+0

Спасибо за ваш ответ, но я действительно не понимаю, что упоминает jgauffin. Наверное, я не могу избежать создания специализированных репозиториев для некоторых классов. Я немного обновлю свой вопрос после следующей встречи, которая началась прямо сейчас ... – Jobo

+0

@jgauffin 1) Я не хочу, чтобы мой бизнес или пользовательский интерфейс занимались проблемами инфраструктуры. 2) Это ваш вопрос. Вы все еще можете работать с неанемическими моделями домена и не делегировать пользовательскому интерфейсу или бизнесу ответственность за создание экземпляра репозитория. –