dan*_*wig 2 domain-driven-design dependency-injection repository entity-framework-4.1
我们的域名模型现在非常贫乏.我们的实体大多是空壳,几乎完全是为了保存值和导航到集合而设计的.
我们使用EF 4.1代码优先ORM,到目前为止的设计是为了保护我们的新手开发人员免受可怕的"LINQ to Entities无法将blablabla转换为商店表达式"异常在早期迭代期间查询上下文时的异常.
我们在EF上有各种聚合根存储库接口.然而,impls中的一些代码块似乎应该是域的责任.只要在域中声明了存储库接口,并且impl在基础结构中(注入依赖关系),将存储库接口作为参数传递给实体(或其他域)类的方法是否被认为是错误的设计?
例如,这会不好?
public class EntityAbc {
public void SaveTo(IEntityAbcRepository repos) {...}
public void DeleteFrom(IEntityAbcRepository repos) {...}
}
Run Code Online (Sandbox Code Playgroud)
如果特定实体需要访问其他聚合根存储库,该怎么办?这样可以吗,为什么?
public void Save() {
var abcRepos = DependencyInjector.Current.GetService<IEntityAbcRepository>();
var xyzRepos = DependencyInjector.Current.GetService<IEntityXyzRepository>();
// work with repositories
}
Run Code Online (Sandbox Code Playgroud)
更新1
我没有提到将代码移动到应用程序层,因为我考虑了一些使用IEntityAbcRepository来涉及业务规则实施的代码.存储库impl应尽可能为vanilla,对吧?它的主要职责应该是对ORM的简单抽象,允许您查找/添加/更新/删除实体.错误?
此外,此问题适用于其他非实体域类的方法 - 工厂,服务,任何模式可能是适当的.重点是,我问的是关于域类的任何方法的问题,而不仅仅是实体类.@Eranga,这是一个可以使用构造函数注入的地方,因为工厂和服务不是ORM的一部分.
然后,应用程序层可以通过将存储库impl注入其构造函数并将其作为参数传递给域服务或工厂来协调流.这是不好的做法吗?
更新2
在这里添加另一个澄清.如果域只需要访问IEntityAbcRepository以执行其Find()方法,该怎么办?在上面的示例中,SaveTo和DeleteFrom方法不会在存储库接口上调用任何添加/更新/删除方法.
到目前为止,为简单起见,我们在单个聚合根存储库接口上组合了find/add/update/delete方法.但我想没有什么可以阻止我们将它们分成2个接口,如下所示:
在这种情况下,将IEntityAbcReadRepository作为参数传递给域方法是不好的做法?
与使用"服务定位器"模式的第二种方法相比,您的第一种方法更好.在第一种方法中,依赖性更明显.
以下是一些链接,解释了为什么"服务定位器"是一个糟糕的选择
这两种解决方案都源于EF不允许您使用构造函数注入的事实.但是,您可以使用属性注入,如本答案中所述.但这并不能保证存在强制依赖.
所以你的第一种方法是更好的解决方案.
| 归档时间: |
|
| 查看次数: |
1470 次 |
| 最近记录: |