【问题标题】:Is it a good design practice to have an interface for each service class in DDD?DDD 中的每个服务类都有一个接口是一种好的设计实践吗?
【发布时间】:2013-10-18 14:54:34
【问题描述】:

我刚刚开始使用 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 中是否是一个好的做法。

【问题讨论】:

  • 接口很好,但是你应该看看注入(特别是constructor injection)而不是使用服务位置。
  • 请阅读我对马特·惠顿的回答

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


【解决方案1】:

使用接口几乎总是更可取和良好的做法 - 所以第二个示例中的内容更好。

但正如 StuartLC 所提到的,您确实希望将这些依赖项作为构造函数参数注入。

ObjectFactory.GetInstance 实际上是一种服务定位器,它通常不是最好的模式,因为对象没有声明它有什么依赖关系。通常最好将依赖项暴露为构造函数参数并将它们注入。

【讨论】:

  • 我不确定我是否理解您的意思。 (我通过构造函数进行所有注入,StructureMap 找到这些依赖项)请在其他世界告诉我。谢谢。
  • 所以是的,您正在构造函数中解决这些依赖关系,但是您应该将它们作为构造函数的参数。然后创建对象的类会将依赖项注入到对象中。
  • 不,我实际上将它们作为构造函数的参数。当我称之为“IEmployeeService employeeService = ObjectFactory.GetInstance();”时StructureMap 使用所需的参数创建它。 EmployService 的构造函数有两个构造函数参数(IEmployRepository、IShiftModelService)并且没有默认构造函数。
  • 是的,这很好,也是正确的做法。您还可以使用 MVC 依赖解析器将服务注入您的控制器...因此您永远不必在控制器中调用 ObjectFactory.GetInstance - 请参阅此问题 stackoverflow.com/questions/12218300/…
【解决方案2】:

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

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

我没有在我的项目中使用结构映射,但我一直在使用Castle Windsor,另一个依赖注入框架。你也可以看看Ninject

不管怎样,很多框架都有类似的步骤:

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

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);
    }
}

有几个有用的链接:

【讨论】:

    猜你喜欢
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    相关资源
    最近更新 更多