在 DDD 中为每个服务类提供一个接口是否是一种良好的设计实践
本文关键字:一种 是否是 接口 服务 一个 DDD | 更新日期: 2023-09-27 18:36:01
我刚刚开始使用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 中的好做法。
使用接口几乎总是更可取和良好的做法 - 所以你在第二个例子中拥有的更好。
但正如 StuartLC 所提到的,您真的希望将这些依赖项作为构造函数参数注入。
ObjectFactory.GetInstance 实际上是一种服务定位器,它通常不是最好的模式,因为对象不会声明它有什么依赖项。通常,最好将依赖项公开为构造函数参数并注入它们。
是的,当您使用 DI(依赖注入)框架时,可以为每个实现使用一个接口。
您应该避免ObjectFactory.GetInstance<IShiftModelService>()
,并让您的框架使用 YourImplementationOfControllerFactory
自动解析依赖项。
我没有在我的项目中使用结构图,但我一直在使用Castle Windsor,另一个依赖注入框架。你也可以看看Ninject。
无论如何,对于许多框架,有一些步骤是相似的:
- 编写控制器工厂的自定义实现 - 一个类继承
DefaultControllerFactory
. - 注册容器应解析的类型。
- 引导容器在
Global.asax.cs
. - 在
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);
}
}
有几个有用的链接:
- Castle Windsor for StructureMap 用户
- 温莎教程 - ASP.NET MVC 3 应用程序
- ASP.NET MVC 提示:使用结构图进行依赖注入
- 另一个我关于温莎城堡的SO答案设置步骤