数据实体,域实体和DDD中的存储库

时间:2018-02-23 19:54:07

标签: c# entity-framework domain-driven-design ddd-repositories

我试图绕过DDD,但我被卡住了。 这就是我设置项目的方式:

Data Access Layer
 -Entity models that map to the db
 -Db connection stuff
 -Repositories implementations

Domain Layer
 -Models that represent the DAL entity models
 -Repositories interfaces

Application Layer
 -MVC application that uses Domain models

我在这里看到的第一个问题是Domain模型与Entity模型完全相同,我有一个严重的问题:实体模型显然已经配置了验证,例如" max length& #34;," nullable"," required"等等。现在,为了符合我所理解的DDD,我不能在任何地方直接使用这些模型,除了DAL ,所以我创建了我的域层。在域层中,我将所有这些验证规则重复用于UI验证,更糟糕的是,如果我需要更改规则,我将不得不在两个地方更改它:DAL和域

示例:

User Entity in DAL
Name (required)
Last name (required)
Email (required, maxlen 120)
Username (required, maxlen 120)

User Domain Model
Name (required)
Last name (required)
Email (required, maxlen 120)
Username (required, maxlen 120)

我觉得非常奇怪的另一件事是该架构中的存储库组织。 按照我的阅读,我在Domain层创建了一个GenericRepository接口和一个继承GenericRepository的UserRepository接口。 我在DAL中实现了GenericRepository,实现为用于创建存储库的实体类型创建了一个DAO。到目前为止,非常好。

然后,我继续实现UserRepository,这里我有另一个问题:UserRepository接口需要Domain User模型,当我尝试在DAL中实现接口时,我需要使用Domain User模型来实现它,这导致为域模型而不是DAL模型创建DAO,这没有任何意义。修复它的唯一方法是引用域层中的DAL,这是错误的。

Domain Layer:

public interface IGenericRepository<TEntity>
{
    TEntity FindById(TKey id);
}

public interface IUserRepository : IGenericRepository<Domain.User>
{
    Task<User> FindByUserNameAsync(string userName);
}


DAL:

public abstract class GenericRepository<TEntity> : IGenericRepository<TEntity>
{
    protected DbContext ctx;
    protected DbSet<Entity> dbSet;

    public GenericRepository(DbContext context)
    {
        ctx = context;
        dbSet = ctx.Set<TEntity>();
    }

    public virtual TEntity FindById(TKey id)
    {
        return dbSet.Find(id);
    }
}

 public class UserRepository : GenericRepository<Domain.Models.User>, IUserRepository
{
    public UserRepository(DbContext context)
        : base(context)
    {
       // THIS WILL CREATE A DAO FOR A DOMAIN MODEL
    }

    // rest of code...
}

任何人都可以了解我在DDD中缺少的东西吗?

2 个答案:

答案 0 :(得分:0)

您的问题以及您对DDD的疑问是有道理的,因为您正在从代码角度接近主题。

你似乎陷入了你的代码重复&#34;你将会错过更大的画面。

来自wikipedia定义:

  

域驱动设计(DDD)是一种通过将实现连接到不断发展的模型来满足复杂需求的软件开发方法。域驱动设计的前提如下:   
- 将项目的主要重点放在核心域和域逻辑上 -   基于域模型的复杂设计 -   启动技术专家和领域专家之间的创造性协作,以迭代方式完善解决特定领域问题的概念模型。

如果您的模型需要的唯一业务逻辑是字符串字段的验证,那么除了DDD之外,您可能还需要另一种方法来开发您的应用程序。

如何考虑DDD: DDD是一种开发理念(由Eric Evans定义),专注于为复杂域编写软件的开发团队。这些团队需要明确的界限,因为一个模型中的变更不应影响其他团队模型,进度等(因此您的代码重复)。

如何不考虑DDD: 它不是具有预定义代码适用模式的框架。

团队启动DDD的常见问题:

  • 过分强调战术模式的重要性: 而不是解决您的实际业务问题,专注于聚合根,价值对象等。
  • 专注于代码而不是DDD的原则:代码应该是DDD进程的最后一次迭代。真正的工作是理解业务问题,并尝试找到一个易于理解的解决方案(消除问题的复杂性)。

您可以在Patterns, Principles, and Practices of Domain-Driven Design找到更多陷阱以及如何学习应用DDD的建议 (陷阱的例子来自本书第9章)

答案 1 :(得分:-2)

  

任何人都可以了解我在DDD中缺少的东西吗?

你没有遗漏任何东西。 DDD适用于您不希望实体(存储)模型与内存中域模型相同的情况。当您的域模型具有大量复杂行为时,IE并不主要用作查找参考数据和记录事务的数据模型。

您刚刚了解到,对于许多应用程序而言,DDD是浪费时间。