DDD和IOC容器

时间:2010-05-24 12:47:44

标签: c# domain-driven-design ioc-container

我对DDD很新,我试图使用IOC来放松紧密耦合的层:)

我的C#网络应用程序由 UI 持久性层组成。我的持久性图层引用了我的图层,并包含我的具体存储库实现和nhibernate映射。目前,我的用户界面引用了我的图层。

我的问题:如何使用IOC容器将我的持久层中的具体类注入我的层?这是否意味着我的 UI 还应该引用我的持久性图层?

3 个答案:

答案 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容器处理“如何”或“什么”。

如何设置取决于您的系统的内容。我通常有这样的设置:

  1. 网站 - &gt;引用2个程序集:Common(扩展方法,业务实体等),Service(如UI中的调用点 - 缓存到持久存储的层等)
  2. 服务 - &gt;引用1汇编:存储库
  3. 存储库 - &gt;没有提及。
  4. 然后我会在UI中注入一个服务层的具体实现,并将存储库的具体实现注入服务层。

    如果您再查看解决方案属性,请查看Web项目,您将只看到2个依赖项。特别是,它不依赖于持久层。

    如果要传递对象,请考虑将表格投影到POCO(包含在公共程序集中)。

答案 1 :(得分:1)

不,我不会在模型或视图中注入持久性。

您确实需要一个位于视图和其他视图之间的单独服务层。服务层了解工作单位;它协调持久性和模型对象以满足用例。

模型对象无需知道哪个图层使用它们。他们表达了领域概念。

答案 2 :(得分:1)

您的UI不应该引用您的持久层。使用IoC,您可以将“下层”的关注点以“堆栈”方式注入其上方的层中。

因此,您的IoC配置会将持久性实现注入您的域层。除了用于保存和检索域对象的接口之外,域层应该不知道持久性。这些接口由持久层中的类/逻辑实现。