我对DDD很新,我试图使用IOC来放松紧密耦合的层:)
我的C#网络应用程序由 UI ,域和持久性层组成。我的持久性图层引用了我的域图层,并包含我的具体存储库实现和nhibernate映射。目前,我的用户界面引用了我的域图层。
我的问题:如何使用IOC容器将我的持久层中的具体类注入我的域层?这是否意味着我的 UI 还应该引用我的持久性图层?
答案 0 :(得分:2)
Dave是对的,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>();
});
}
你的所有UI都知道它会调用一些实现某些接口的Domain类。 你的所有Domain都知道它会调用一些Persistence类,它会改变一些接口。
上面的DI容器处理“如何”或“什么”。
如何设置取决于您的系统的内容。我通常有这样的设置:
然后我会在UI中注入一个服务层的具体实现,并将存储库的具体实现注入服务层。
如果您再查看解决方案属性,请查看Web项目,您将只看到2个依赖项。特别是,它不依赖于持久层。
如果要传递对象,请考虑将表格投影到POCO(包含在公共程序集中)。
答案 1 :(得分:1)
不,我不会在模型或视图中注入持久性。
您确实需要一个位于视图和其他视图之间的单独服务层。服务层了解工作单位;它协调持久性和模型对象以满足用例。
模型对象无需知道哪个图层使用它们。他们表达了领域概念。
答案 2 :(得分:1)
您的UI不应该引用您的持久层。使用IoC,您可以将“下层”的关注点以“堆栈”方式注入其上方的层中。
因此,您的IoC配置会将持久性实现注入您的域层。除了用于保存和检索域对象的接口之外,域层应该不知道持久性。这些接口由持久层中的类/逻辑实现。