简体   繁体   English

C# 域 Model + 存储库:放置加载实体的代码的位置

[英]C# Domain Model + repository: Where to put code that loads an entity

I have a model class which is loaded from a "GetById" method in my repository class.我有一个 model class,它是从我的存储库 class 中的“GetById”方法加载的。 I now need to add additional properties to this entity, which aren't saved in the database, but are calculated by a service class.我现在需要向该实体添加其他属性,这些属性并未保存在数据库中,而是由服务 class 计算得出。 Something like:就像是:

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);

So in order to load/saturate a MyEntity object, I need to load from the db, and then call the generator to determine the "woo factor" (ahem).因此,为了加载/饱和 MyEntity object,我需要从数据库加载,然后调用生成器来确定“woo 因子”(咳咳)。 Where should this code go from an architectural viewpoint?从架构的角度来看,这个代码 go 应该在哪里? Current thoughts:目前的想法:

1) In the repository: I feel like I'm handing too much responsibility to the repo if I add it here. 1)在存储库中:如果我在这里添加它,我觉得我将太多的责任交给了 repo。

2) In the "MyEntity" class. 2)在“我的实体”class。 Add the code in here that perhaps lazy-loads the WooFactor when it is accessed.在此处添加代码,可能会在访问 WooFactor 时延迟加载它。 This would add a lot of dependencies to MyEntity.这会给 MyEntity 添加很多依赖项。

3) A separate service class - seems overkill and un-necessary. 3) 单独的服务 class - 似乎矫枉过正且不必要。

  • If WooFactor is purely dependent on MyEntity properties then it must be done inside MyEntity如果WooFactor完全依赖于MyEntity属性,那么它必须在MyEntity中完成
  • If it requires external info (such as configuration, rules, etc) then it needs to be a separate service outside Repository .如果它需要外部信息(例如配置、规则等),那么它需要是Repository 之外的单独服务。 I would create a WooEntity here with this additional property.我会在这里创建一个带有这个附加属性的WooEntity

In any case, it should never be in the Repository .在任何情况下,它都不应该在Repository中。

Google CQRS.谷歌 CQRS。 What you need to do is to separate the read and write concerns.您需要做的是分离读写关注点。 If the calculation is needed by something else other than the entity, you have your answer in plain sight.如果实体以外的其他事物需要计算,那么您的答案就一目了然。

I ran into similar concerns recently where I needed to aggregate different data to produce my entity.我最近遇到了类似的问题,我需要聚合不同的数据来生成我的实体。 I eventually decided to create a service to handle the construction of my Entity and any actions that happened to the Entity我最终决定创建一个服务来处理我的Entity的构建以及Entity发生的任何操作

Using your example It might look like this:使用您的示例它可能如下所示:

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

In the end this worked out the best for the project as any interaction to the Entity was done via the service.最后,这对项目来说是最好的,因为与Entity的任何交互都是通过服务完成的。

How you manage getting data from the repository is essentially correct - so the best general approach would be to do the same for the service.您管理从存储库获取数据的方式本质上是正确的——因此最好的通用方法是对服务执行相同的操作。 There's a lot of advantage in having a consistent architecture and approach.拥有一致的架构和方法有很多优势。

The big caveat with that is managing the dependencies;最大的警告是管理依赖关系; my general assumption is scenarios like this is that the physical data access is abstracted out - so that the model isn't technically tied to SQL, the file system, etc. using this approach will allow you to expose different data from different repositories in a consistent manner.我的一般假设是这样的场景是物理数据访问被抽象出来 - 因此 model 在技术上与 SQL、文件系统等没有关联。使用这种方法将允许您在不同的存储库中公开不同的数据一致的方式。

  • Your idea of using lazy Load is good;您使用延迟加载的想法很好; and if you abstract out the technical dependencies your main concern with that option goes away.如果您抽象出技术依赖项,您对该选项的主要关注就消失了。
  • A separate service class might seem like overkill but it's a small price to pay if it means it gives you better control over dependencies.单独的服务 class 可能看起来有点矫枉过正,但如果这意味着它可以让您更好地控制依赖关系,那么这是一个很小的代价。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM