Data access layer design in DDD

馋奶兔 提交于 2019-12-01 18:44:35

I think you got this part wrong:

I see another option. The ORM which is a part of the DAL could be asked to store all of the private fields needed to restore the object. But this is impossible if we want to keep the domain model separated from the DAL. The DAL cannot rely on certain private members of the business object.

Domain model does not depend on DAL. Its the other way around, DAL depends on Domain model. ORM has intimate knowledge of Domain Objects, including private fields. There is absolutely nothing wrong with that. In fact this is the best way to implement persistent-ignorance in DDD. This is how the Domain class can look like. Note that

  • fields can be private and readonly
  • public Constructor is only used by client code, not by DAL.
  • no need for property getters and setters
  • Business object is almost 100% ignorant of persistence issues

The only thing DAL/ORM needs is private parameterless consturctor:

public class BusinessObject {
    private readonly string _user;
    private readonly string _domain;

    private BusinessObject(){}

    public BusinessObject(string user, string domain) {
        _user = user;
        _domain = domain;
    }

    public string Email {
        get { return _user + "@" + _domain; }
    }
}

And the magic happens in ORM. Hibernate can restore this object from database using this mapping file:

<class name="BusinessObject" table="BusinessObjects">
    ...
    <property name="_user" column="User" />
    <property name="_domain" column="Domain" />
    ...
</class>

Another aspect of persistence-ignorant domain code is DDD Repository:

Definition: A Repository is a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.

Repository interface belongs to Domain and should be based on Ubiquitous Language as much as possible. Repository implementation on the other hand belongs to DAL (Dependency Inversion Principle).

public class BusinessObject
{
    private string _user;
    private string _domain;

   public BusinessObject(string email)
   {
      string[] s = value.Split("@");
      _user = s[0];
      _domain = s[1];    
   } 

   public BusinessObject(string user, string domain)
    {
        _user = user;
        _domain = domain;
    }

    public string Email
    {
        get { return _user + "@" + _domain; }
    }
}

One simple solution is to just have your DAL call new BusinessObject(email)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!