如何将领域类与EF代码第一层分离并在项目中实现DDD
Posted
技术标签:
【中文标题】如何将领域类与EF代码第一层分离并在项目中实现DDD【英文标题】:How to separate domain classes from EF code first layer and implement DDD in project 【发布时间】:2017-03-14 10:29:27 【问题描述】:我正在尝试首先使用 EF 代码来控制 DDD。我看到人们首先使用 EF 代码,然后域类驻留在相同的类中。看一个小例子。
public class TestDBContext : DbContext
public TestDBContext()
: base("name=TestDBContext")
protected override void OnModelCreating(DbModelBuilder modelBuilder)
//modelBuilder.Configurations.Add(new vwCustomerConfiguration());
Database.SetInitializer<TestDBContext>(null);
public DbSet<Customer> Customer get; set;
public DbSet<Addresses> Addresses get; set;
public DbSet<Contacts> Contacts get; set;
public virtual DbSet<vwCustomer> vwCustomers get; set;
public DbSet<vwMyCustomers> vwMyCustomers get; set;
客户、地址、联系人和所有域类都在同一个项目中,但我想将所有这些域类放在不同的项目中。
只需查看我正在考虑实施的新项目层次结构。所有项目名称都以我的公司开头,然后是项目名称
在这里
1) Impex.Domain
2) Impex.Storage
3) Impex.Business
4) Impex.UI
所以我将有 4 层,分别是域、存储、业务和 UI。 Storage、Business 和 UI 这 3 层会有 Domain 层的引用,因为 Storage、Business 和 UI 这 3 层可能会用到领域类。
UI 将数据传递给业务层并从业务层接收数据。业务层再次与存储层对话,存储层将首先实现 EF 代码以与 DB 交互。
如果我能在 4 层之后成功完成我的项目,那么人们应该考虑我的项目是否基于 DDD 模式?
所以告诉我我的想法是否正确。请告诉我您的所有建议和指导。如果有人可以预见任何问题,那么也请详细了解我。谢谢
【问题讨论】:
看看这个amazon.co.uk/Modern-Web-Development-Understanding-technologies/…,它对你的帮助比你在这里得到的许多可能的答案要多。在这里你会得到很多回应,通常会与下一个发生冲突。购买此书,阅读此书,然后根据这让您思考的内容做出自己的判断和决定 我尝试将 DDD 与 EF 相结合的经验是,您可以使用您的域类型作为您的 EF 类型,但您必须在此过程中做出一些妥协。如果你想保持你的域完全干净并且与持久性无关 - 特别是如果你的域已经或将变得复杂 - 拥有一组作为你的 EF 类型的持久性模型,并将它们隐藏在你的存储库后面(我假设存储是?),并将两者完全分开。这是更多的工作,所以你需要评估它是否值得。 【参考方案1】:您的问题似乎主要围绕您的解决方案的结构,就像我们行业中的大多数事情一样,一旦您了解了事物的原理(在本例中为 DDD),该结构似乎会自行解决。
我会指出一些事情来帮助你前进
1) Impex.Domain
保持你的实体干净不要从这个项目中引用 EF 在您的实体和聚合中而不是在“业务”层中捕获您的业务逻辑,您的实体应该响应事件和操作,而不是拥有一个告诉它要做什么的“层”作为一个糟糕的例子,做类似的事情
employee.takeLeave(days)
代替
employee.daysOff = days;
即修改实体的状态应该在实体内部捕获。
2) Impex.Storage
由于您使用的是 EF(并且不会用 EF 相关属性污染您的域模型),您将不得不使用 Fluent Api 来配置您的 EF 模型(请参阅msdn、ef tuts 和 SO 到得到一些想法)特别是,这里需要配置主键和索引。类似
modelBuilder.Entity<Employee>().HasKey(t => t.EmployeeID);
除了这里没有任何东西使用标准存储库模式等。
3) Impex.Business & Impex.UI
如第 1 点所述,拥有business
层没有意义,而该层将是Application
或Service
层,在这里您将加载实体或聚合并调用待完成的工作。
此外,该层的职责是在 ViewModel 和/或请求和响应 POCO 之间进行映射(发送到您的 UI/Api 和从您的 UI/Api 发送),您不会在域边界之外公开您的域模型,请参阅 hexagonal architecture
最后一点:
DDD 并不规定架构!这是一组指导您的原则,但您可以将其实现为 1 层、3 层、CQRS 或您喜欢的任何其他架构模式,只要您遵守 DDD 的租户即可。
祝你好运。
【讨论】:
以上是关于如何将领域类与EF代码第一层分离并在项目中实现DDD的主要内容,如果未能解决你的问题,请参考以下文章