dependency-injection - 将存储库接口(interface)作为参数传递给域类上的方法是否被认为是糟糕的设计?

标签 dependency-injection entity-framework-4.1 domain-driven-design repository

我们的领域模型现在非常贫乏。我们的实体大多是空壳,几乎纯粹是为保存值和导航到集合而设计的。

我们使用的是 EF 4.1 代码优先 ORM,到目前为止的设计一直是保护我们的新手开发人员在早期迭代期间查询上下文时免受可怕的“LINQ to Entities 无法将 blablabla 转换为存储表达式”异常。

我们有各种基于 EF 的聚合根存储库接口(interface)。然而,impls 中的一些代码块似乎应该是域的责任。只要在域中声明了存储库接口(interface),并且 impl 在基础架构中(依赖注入(inject)),将存储库接口(interface)作为参数传递给实体(或其他域)类上的方法是否被认为是糟糕的设计?

例如,这会很糟糕吗?

public class EntityAbc {
    public void SaveTo(IEntityAbcRepository repos) {...}
    public void DeleteFrom(IEntityAbcRepository repos) {...}
}

如果特定实体需要访问其他聚合根存储库怎么办?这会好还是不好,为什么?
public void Save() {
    var abcRepos = DependencyInjector.Current.GetService<IEntityAbcRepository>();
    var xyzRepos = DependencyInjector.Current.GetService<IEntityXyzRepository>();
    // work with repositories
}

更新 1

我没有提到将代码移动到应用程序层,因为我认为一些使用 IEntityAbcRepository 的代码涉及业务规则执行。存储库 impl 应该尽可能简单,对吗?它的主要职责应该只是对 ORM 的简单抽象,允许您查找/添加/更新/删除实体。错误的?

此外,这个问题适用于其他非实体域类的方法——工厂、服务,任何可能合适的模式。重点是,我问的是关于域类上的任何方法的问题,而不仅仅是实体类。 @Eranga,这是您可以使用构造函数注入(inject)的地方,因为工厂和服务不是 ORM 的一部分。

然后,应用层可以通过将存储库 impl 注入(inject)到其构造函数中来协调流程,并将其作为参数传递给域服务或工厂。这是不好的做法吗?

更新 2

在此处添加另一个说明。如果域只需要访问 IEntityAbcRepository 以执行其 Find() 方法怎么办?在上面的示例中,SaveTo 和 DeleteFrom 方法不会调用存储库接口(interface)上的任何添加/更新/删除方法。

到目前为止,为了简单起见,我们已经在单个聚合根存储库接口(interface)上组合了 find/add/update/delete 方法。但我想没有什么能阻止我们将它们分成 2 个接口(interface),如下所示:
  • IEntityAbcReadRepository <--定义所有查找方法签名
  • IEntityAbcWriteRepository <-- 定义所有添加/更新/删除方法信号

  • 在这种情况下,将 IEntityAbcReadRepository 作为参数传递给域方法会是不好的做法吗?

    最佳答案

    与使用“服务定位器”模式的第二种方法相比,您的第一种方法更好。在第一种方法中,依赖性更加明显。

    这里有一些链接解释了为什么“服务定位器”是一个不好的选择

  • Is it bad to use servicelocation instead of constructor injection ...
  • Singleton Vs ServiceLocator
  • Say no to ServiceLocator

  • 这两种解决方案都源于 EF 不允许您使用构造函数注入(inject)这一事实。但是,您可以按照 in this answer 的说明使用属性注入(inject)。 .但这并不能保证存在强制依赖项。

    所以你的第一种方法是更好的解决方案。

    关于dependency-injection - 将存储库接口(interface)作为参数传递给域类上的方法是否被认为是糟糕的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8500203/

    相关文章:

    java - OpenJPA、 Jersey 、JUnit : Using a different persistence unit for my unit tests?

    javascript - AngularJS - DI 系统如何知道参数的名称?

    entity-framework - 使用 EF Code-First 模型在保存或验证之前执行逻辑

    entity-framework - 如何在 Entity Framework 5 中包含子对象的子对象

    domain-driven-design - DDD : inter-domain referencing design issue?

    generics - Dagger 2 Generic Type 类注入(inject)错误

    javascript - 循环依赖,当 ovveriding ExceptionHandler

    entity-framework - EF 4.1, 继承与共享主键关联 => 指定表达式的 ResultType 不兼容

    java - 由于在 REST 中使用 HATEOAS 而导致循环依赖

    c# - Entity Framework 数据注释对 DDD 和关注点分离有害吗?