Rob*_*ode 1 domain-driven-design entity-framework dependency-injection application-layer business-layer
我正在使用具有以下层的Entity Framework 6在WinForms应用程序上工作:
当用户从UI单击"保存"按钮时,它将调用"应用程序"层中的应用程序服务并传入请求.然后,应用程序服务使用该请求调用域服务.域服务调用域模型中的多个实体,以对请求中使用的数据执行验证.
域模型中的一个或多个验证需要来自存储库的信息,以确定从表示层接收的请求中的数据是否符合某些业务规则.
我正在考虑两个方案来解决这个问题.
让应用程序服务从存储库中检索所需的信息以进行验证,并将这些值传递给域服务,域服务将调用域模型和实体来验证传入的规则和值请求.然后,当域服务完成其验证时,让Application Service保存请求,这将导致将控制权返回给同步等待验证完成的应用程序服务.如果我这样做,那么域层将没有对存储库的直接或间接(注入)引用.如果我这样做,域服务的单元测试会更容易,因为没有注入任何内容来执行验证.它所需要的一切都已经传入.缺点是一些业务知识被放入应用服务,因为现在它需要知道要检索哪个存储库信息以验证请求.
在调用域服务以验证请求时,请将Application Service的实例注入其中.然后,域服务可以使用注入的应用程序服务从存储库获取信息,其服务合同在域层中定义.一旦所有信息都可用,它将根据需要传递给各个实体以验证规则和值.验证完成后,域服务使用注入的应用程序服务保存请求.域服务完成并退出后,它会将保存操作的状态返回给已等待验证完成的应用程序服务.然后,外部等待应用程序服务可以将保存结果返回给UI.我在这里遇到的一个问题是,在对域服务进行单元测试时,我将不得不模拟注入的应用服务.
哪个选项或其他行动方案可以更好地解决?提前致谢.
"应该将应用程序服务注入域服务"
没有永不!
解析来自应用程序服务的数据并将其传递给域服务通常很好,但是如果您认为域逻辑正在泄漏,那么您可以应用接口隔离原则(ISP)并根据合同是在域中定义接口需要查询"通缉数据".在您的存储库或任何其他可以完成任务的对象上实现该接口,并将其注入您的域服务.
例如(伪代码)
//domain
public interface WantedDataProvider {
public WantedData findWantedData(...) {}
}
public class SomeDomainService {
WantedDataProvider wantedDataProvider;
}
//infrastructure
public class SomeRepository implements WantedDataProvider {
public WantedData findWantedData(...) {
//implementation
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
我有一个请求聚合根与员工姓名.一条规则是员工必须是全职而非承包商
如果要在聚合上存在执行验证的信息,您也可以将此AR用作其他AR的工厂.假设员工持有合同类型......
Employee employee = employeeRepository.findById(employeeId);
Request request = employee.submitRequest(requestDetails); //throws if not full time
requestRepository.add(request);
Run Code Online (Sandbox Code Playgroud)
请注意,除非您更改聚合边界,否则只能在此处使不变量最终保持一致,但与其他解决方案相同.
| 归档时间: |
|
| 查看次数: |
199 次 |
| 最近记录: |