关于持久层和 InternalsVisibleTo 的 .Net 架构清洁架构问题

.Net architecture Clean Architecture question on Persistence layer and InternalsVisibleTo

假设,我有一个具有只读 ID 属性 的实体,例如:

public int Id { get; }

然后我有一个持久层,它实现实体存储库并在实体存储到数据库时分配新的 Id 值:

public async Task AddToDb(MyEntity ent) { ... };

现在,此方法可以 return 通过读取 Db 中的实体,但我不喜欢发出另一个网络请求(在这种情况下没有并发)。所以我最好将新的 Id 分配给传递的实体。但是 Id 是只读的。我正在考虑通过使用 InternalsVisibleTo 属性使持久层对域层“友好”。

好吧,这似乎有点老套,我知道数据库应该是真实的来源。还有其他选择吗?我在做某事吗 unnecessary/wrong?

除了使用 InternalsVisibleTo 之外,spring 需要注意的几个可能选项是:

  1. 您可以利用 C#9 中引入的 init 访问器来执行您需要的操作吗?

    public int Id { 得到;在里面; }

这将允许您将 属性 保持为只读,但您可以在对象初始化时分配它。

  1. 遵循更多的 CQRS 方法并拥有“单独的数据持久性模型”和“数据视图模型”并从“创建新对象视图模型”中省略 id 属性,使 id 属性 在持久性模型中设置(或如前所述可初始化),然后 return 在实际提交到数据库之前来自持久层的 id:

在面向外部的项目中(视图或 API 或其他)

public MyEntityViewModel()
{ 
  string SomeProperty { get; set;}
}

然后在持久层

public MyEntity()
{ 
   public int Id { get; init; }
   string SomeProperty { get; set;}
}

public async Task<int> AddToDb(MyEntityViewModel ent) 
{
   var newEnt = new MyEntity(){ Id = 1234 };
   
   //map the contents of the ViewModel to the peristance Model
   newEnt.SomeProperty = ent.SomeProperty;

   ///code to commit to DB.

   return newEnt.Id;
};

这里可以就每个模型的位置、哪个组件应该负责映射等进行各种讨论,但我希望这能传达总体思路。

  1. 使 Id 属性 可设置,然后在 public async Task AddToDb(MyEntity ent) 中用持久层确定的值简单地覆盖它。这可以说是最简单的选项,它允许您的持久层最终控制,而不必执行大量费力的逻辑。