victor
victor

Reputation: 1552

Data Entities, Domain entities and the Repositories in DDD

I'm trying to get my head around DDD but I'm stuck. This is how I setup my project:

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

The first problem I see here is that the Domain models are exactly the same as the Entity models, and I have a serious problem with this: the entity models obviously have validation configured into them, things like "max length", "nullable", "required", etc. Now, to conform to what I understand is DDD, I can't directly use these models anywhere, except the DAL, so I created my domain layer. In the domain layer, I have all these validation rules duplicated for UI validation, and what's even worse, is that if I need to change a rule, I will have to change it in two places: the DAL and the Domain.

Example:

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)

Another thing that I find very weird is that the repositories organization in this architecture. Following what I read, I created a GenericRepository interface, and a UserRepository interface, which inherits the GenericRepository, all in the Domain layer. I implemented the GenericRepository in the DAL, and the implementation creates a DAO for the type of the entity used to create the repository. So far, so good.

Then, I proceeded to implement the UserRepository, and here I have another problem: the UserRepository interface expects the Domain User model, and when I try to implement the interface in the DAL, I need to implement it using the Domain User model, which causes the DAO to be created for a Domain model, not a DAL model, and this doesn't make any sense. The only to fix it would be to reference the DAL in the Domain layer, which is wrong.

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...
}

Can anybody shed a light on what I'm missing from DDD?

Upvotes: 0

Views: 993

Answers (1)

Eirini Graonidou
Eirini Graonidou

Reputation: 1566

Your question and your doubt against DDD makes sense, because you are approaching the subject from the code-point-of-view.

You seem to stuck at your "code duplication" and you are about to miss the bigger picture.

From wikipedia definition:

Domain-driven design (DDD) is an approach to software development for complex needs by connecting the implementation to an evolving model. The premise of domain-driven design is the following:
- placing the project's primary focus on the core domain and domain logic
- basing complex designs on a model of the domain
- initiating a creative collaboration between technical and domain experts to iteratively refine a conceptual model that addresses particular domain problems.

If the only business logic that your model needs, is the validation of string fields then you might need another approach,other than DDD, to develop your application.

How to think about DDD: DDD is a development philosophy (defined by Eric Evans) and has focus on development teams writing software for complex domains. These teams need clear boundaries because a change, that is to come in one model, should not affect the other's team model, progress etc (therefore you have your code duplication).

How not to think about DDD: It is not a framework with predefined code applicable patterns.

Common problems for teams starting DDD:

  • Overemphasizing the importance of tactical patterns: instead of solving your real business problem, focus on aggregate roots, value objects etc..
  • Focusing on code rather than the principles of DDD: the code should be the last iteration of the DDD process. The real work is understanding the business problem and try to find a solution that is simple to understand (take away the complexity of a problem).

More pitfalls as well as advice how to learn to apply DDD you can find in Patterns, Principles, and Practices of Domain-Driven Design (example of pitfalls are taken from chapter 9 of this book)

Upvotes: 1

Related Questions