Дейв прав, цель 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-контейнером выше.
Как вы настраиваете то, что зависит от вашей системы. У меня обычно есть эта настройка:
- Веб-сайт -> ссылается на 2 сборки: Common (методы расширения, бизнес-объекты и т. Д.), Service (например, точка вызова из UI-уровней при кэшировании в постоянное хранилище и т. Д.)
- Сервис -> Ссылки 1 сборка: Репозиторий
- Репозиторий -> ничего не ссылается.
Затем я бы внедрил конкретную реализацию уровня службы в пользовательский интерфейс и внедрил конкретную реализацию хранилища в уровень службы.
Если вы посмотрите на свойства своего решения, посмотрите на веб-проект, вы увидите только 2 зависимости. В частности, это не будет зависеть от персистентного слоя.
Если вы хотите обойти объекты, рассмотрите возможность проецирования ваших таблиц в POCO (содержится в Общей сборке).