在DDD中为每个服务类设置一个接口是一个很好的设计实践吗?

时间:2013-10-18 14:54:34

标签: c# asp.net-mvc dependency-injection domain-driven-design inversion-of-control

我刚刚开始使用DDD进行设计(我没有老师的经验)

我有一些域服务类在某些方面必须互相引用。所以我决定通过构造函数注入引用。

当我创建一个包含大量要在控制器中显示的数据的视图时,我必须创建一堆服务(其中一些相互引用)

此时我的控制器的第一行看起来像这样:

        EmployeeRepository employRepository = new EmployeeRepository();
        ShiftModelRepository shiftModelRepository = new ShiftModelRepository();
        ShiftModelService shiftModelService = new ShiftModelService(shiftModelRepository);
        EmployeeService employeeService = new EmployeeService(employRepository, shiftModelService);
        OvertimeRepository overtimeRepository = new OvertimeRepository();
        OvertimeService overtimeService = new OvertimeService(overtimeRepository, employeeService);

但我开始为服务创建接口并使用IoC控制器(名为StructureMap)

现在同一个控制器的第一行看起来像这样:

        IShiftModelService shiftModelService = ObjectFactory.GetInstance<IShiftModelService>();
        IOvertimeService overtimeService = ObjectFactory.GetInstance<IOvertimeService>();
        IEmployeeService employeeService = ObjectFactory.GetInstance<IEmployeeService>();

我认为使用它会好得多,但我知道它是否是DDD的好习惯。

2 个答案:

答案 0 :(得分:2)

使用接口几乎总是优先考虑并且是良好的做法 - 所以你在第二个例子中所拥有的更好。

但正如StuartLC所提到的那样,你真的想看看将这些依赖项注入构造函数参数。

ObjectFactory.GetInstance实际上是一种服务定位器,它通常不是最好使用的模式,因为对象没有声明它具有哪些依赖项。通常最好将依赖项公开为构造函数参数并将它们注入。

答案 1 :(得分:2)

是的,当您使用DI(依赖注入)框架时,可以在每个实现中使用一个接口。

您应该避免ObjectFactory.GetInstance<IShiftModelService>()并让您的框架使用YourImplementationOfControllerFactory自动解决依赖关系。

我没有在我的项目中使用Structure Map,但我一直在使用Castle Windsor,另一个依赖注入框架。您也可以查看Ninject

无论如何,许多框架都有类似的步骤:

  1. 编写一个控制器工厂的自定义实现 - 一个类 继承DefaultControllerFactory
  2. 容器应解决的注册类型。
  3. Global.asax.cs中的引导容器。
  4. Global.asax.cs
  5. 中设置控制器工厂的实例

    Global.asax.cs:

    public class MvcApplication : System.Web.HttpApplication
    {    
        protected void Application_Start()
        {
            /* code that bootstraps your container */
    
            //Set the controller builder to use our custom controller factory
            var controllerFactory = new YourControllerFactory();
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
        }
    }
    

    有几个有用的链接: