Контейнеры DDD и IOC - PullRequest
       44

Контейнеры DDD и IOC

4 голосов
/ 24 мая 2010

Я довольно новичок в DDD, и я пытаюсь использовать МОК, чтобы ослабить мои тесно связанные слои:)

Веб-приложение My C # состоит из слоя UI , domain и persistence . Мой слой persistence ссылается на мой слой domain и содержит мои конкретные реализации репозитория и отображения nhibernate. В настоящее время мой UI ссылается на мой домен layer.

Мой вопрос: как мне использовать контейнер IOC для внедрения моих конкретных классов в моем слое персистентности в мой слой domain ? Означает ли это, что мой UI должен также ссылаться на мой persistence layer?

Ответы [ 3 ]

2 голосов
/ 25 мая 2010

Дейв прав, цель DI и IOC - свободно связать компоненты вашей системы.

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

Хорошими контейнерами .NET IoC являются StructureMap (мой выбор), Ninject и Castle Windsor.

Существует несколько способов реализации DI / IoC, наиболее предпочтительным является использование интерфейсов.

У вас будет интерфейс для вашего уровня сохраняемости:

public interface IPersistantStorage
{
    List<Foo> GetStuff();
    void AddStuff(Foo f);
}

Аналогично для слоя вашего домена:

public interface IDomainManager
{
    List<Foo> GetStuff();
    void AddStuff(Foo f);
}

Затем реализуйте конкретные классы для каждого.

Выбранный вами контейнер IoC затем «внедрит» конкретные классы в конструктор.

Вот пример того, как это работает с StructureMap:

public class SomeClassInUILayerThanNeedsToGetSomeThing
{
     IDomainManager domain;

     public SomeClassInUILayerThanNeedsToGetSomeThing(IDomainManager realDomain)
     {
         this.domain = realDomain;
     }

     public List<Foo> GetSomethingFromSomewhere()
     {
         return domain.GetStuff();
     }
}

Затем в загрузчике StructureMap (обычно вызывается в событии запуска вашего приложения - Global.asax)

public static void ConfigureIoCFramework()
        {
            ObjectFactory.Initialize(x =>
            {
                   x.For<IDomainManager>().Use<DomainManager>();
                   x.For<IPersistantStorage>.Use<NHibernateStorage>();
            });
        }

Все, что знает ваш пользовательский интерфейс, - это вызов некоторого класса Domain, который реализует некоторый интерфейс. Все, что знает ваш Домен, это то, что он будет вызывать некоторый класс Постоянства, который реализует некоторый интерфейс.

«Как» или «Что» обрабатывается DI-контейнером выше.

Как вы настраиваете то, что зависит от вашей системы. У меня обычно есть эта настройка:

  1. Веб-сайт -> ссылается на 2 сборки: Common (методы расширения, бизнес-объекты и т. Д.), Service (например, точка вызова из UI-уровней при кэшировании в постоянное хранилище и т. Д.)
  2. Сервис -> Ссылки 1 сборка: Репозиторий
  3. Репозиторий -> ничего не ссылается.

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

Если вы посмотрите на свойства своего решения, посмотрите на веб-проект, вы увидите только 2 зависимости. В частности, это не будет зависеть от персистентного слоя.

Если вы хотите обойти объекты, рассмотрите возможность проецирования ваших таблиц в POCO (содержится в Общей сборке).

1 голос
/ 24 мая 2010

Ваш пользовательский интерфейс НЕ должен ссылаться на ваш уровень персистентности.Используя IoC, вы добавляете проблемы нижнего уровня на уровень выше его в виде «стека».

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

1 голос
/ 24 мая 2010

Нет, я бы не стал вводить постоянство ни в модель, ни в представление.

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

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

...