【问题标题】:C# Domain Model + repository: Where to put code that loads an entityC# 域模型 + 存储库:将加载实体的代码放在哪里
【发布时间】:2011-08-17 17:37:02
【问题描述】:

我有一个模型类,它是从我的存储库类中的“GetById”方法加载的。我现在需要向这个实体添加额外的属性,这些属性没有保存在数据库中,而是由服务类计算得出的。比如:

public class MyEntity
{
    public int ThingId { get; set; };
    public string ThingName { get; set; }

    // Set from the service
    public int WooFactor { get; set; }
}

public class WooFactorGenerator
{
    public int CalculateWooFactor(MyEntity thing); // Hits other services and repo's to eventually determine the woo factor.
}

// Code to get a "MyEntity":

var myEntity = repo.GetById(1);
var gen = new WooFactorGenerator();
myEntity.WooFactor = gen.CalculateWooFactor(myEntity);

所以为了加载/饱和一个 MyEntity 对象,我需要从数据库加载,然后调用生成器来确定“woo 因子”(咳咳)。从架构的角度来看,这段代码应该去哪里?目前的想法:

1) 在存储库中:如果我在这里添加它,我觉得我将太多的责任交给了 repo。

2) 在“MyEntity”类中。在此处添加代码,可能会在访问 WooFactor 时延迟加载它。这会给 MyEntity 添加很多依赖项。

3) 一个单独的服务类 - 似乎矫枉过正且不必要。

【问题讨论】:

    标签: c# architecture domain-driven-design repository-pattern cqrs


    【解决方案1】:
    • 如果WooFactor 完全依赖于MyEntity 属性,那么它必须在MyEntity 内完成
    • 如果它需要外部信息(例如配置、规则等),那么它需要是一个单独的服务在存储库之外。我会在这里使用这个附加属性创建一个WooEntity

    无论如何,它都不应该在Repository中。

    【讨论】:

    • 谢谢。 WooFactor 本身不依赖于 MyEntity 属性,但“WooFactorGenerator”确实需要访问它们作为其工作的一部分。它确实依赖于其他存储库来解决这个问题。
    【解决方案2】:

    谷歌 CQRS。您需要做的是分离读写关注点。如果实体以外的其他事物需要计算,那么您的答案就一目了然。

    【讨论】:

    • 谢谢。所以你说我应该实现一个查询层,它带回代表对象的 DTO 并绕过域层。
    • 是的。管理状态和供应查询是两件不同的事情。因此,如果您需要 calc 进行状态转换,它属于那里。否则,使用您的域发出的事件更新另一个服务。
    • 状态转换不需要它。在“使用您的域发出的事件更新另一个服务”之前,您一直有我 - 请您稍微扩展一下吗?
    • 根据 CQRS,为读取操作维护一个单独的模型。当您在域中执行更改状态的操作时,请发布事件。该事件由您更新满足查询请求的表的读取端使用。关键是:2个模型,不是一个。保持您的域纯净和业务逻辑所在的位置是一件好事。将读取问题扔到另一个地方可以实现这一点。
    • 对。感谢 CQRS 的提醒。我将进一步研究这一点,并可能对我的代码库进行一些更改以促进这一点。
    【解决方案3】:

    我最近遇到了类似的问题,我需要聚合不同的数据来生成我的实体。我最终决定创建一个服务来处理我的Entity 的构建以及Entity 发生的任何操作

    使用你的例子它可能看起来像这样:

    public MyEntityService
    {
      public MyEntity GetById(int id)
      {
        MyEntity myEntity = _repo.GetById(id);
        myEntity.WooFactor = _wooFactorGenerator.CalculateWooFactor(myEntity);
        return myEntity;
      }
    }
    

    最后,这对项目来说是最好的,因为与 Entity 的任何交互都是通过服务完成的。

    【讨论】:

      【解决方案4】:

      您管理从存储库获取数据的方式基本上是正确的 - 因此最好的通用方法是对服务执行相同的操作。拥有一致的架构和方法有很多优势。

      最大的警告是管理依赖项;我的一般假设是这样的场景是物理数据访问被抽象出来 - 因此模型在技术上不依赖于 SQL、文件系统等。使用这种方法将允许您在一个不同的存储库中公开不同的数据一致的方式。

      • 您使用延迟加载的想法很好;如果您抽象出技术依赖项,您对该选项的主要担忧就会消失。
      • 单独的服务类可能看起来有点矫枉过正,但如果这意味着它可以让您更好地控制依赖关系,那么这是一个很小的代价。

      【讨论】:

      • 我认为是单独的服务类
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多