如何避免域模型中的持久性逻辑?

时间:2010-10-17 19:21:27

标签: c# serialization domain-driven-design persistence

我的域名模型如下:

class Group
{
    private List<Person> persons;

    public void AddPerson(Person p) {
       persons.Add(p);
       DoSideEffect()
    }

    public List<Person> GetPersons() {...}
}

现在我需要坚持下去。通过DDD,我无法向此类添加任何持久性属性,因此xml序列化程序将无法工作。无法使用BinaryFormatter,因为格式应该是可读的。我可以手动调用GetPersons()并坚持使用它们 - 但是我如何加载它们呢?如果我调用AddPerson(),则会产生副作用。副作用应该只发生在一个人“真正”添加到域中,而不是坚持下去。

2 个答案:

答案 0 :(得分:3)

我发现这篇文章已经过时了,但仍然没有答案,所以这里有:

这里的关键是你的模型有缺陷,imo。

组应该是一个域对象,其中包含一个简单的只读集合“人员”(成员?)。检索和持久化组的责任属于GroupRepository,它从持久性存储中加载数据并重新构建对象。

例如:

public class Group
{
    private Collection<Person> _persons;

    public Group(Collection<Person> persons)
    {
        if (persons == null)
            throw new ArgumentNullException("persons");

        _persons = persons;    
    }

    public IEnumerable<Person> Persons
    {
        get { return _persons; }
    }

    public void AddPerson(Person p)
    {
        if (p == null)
            throw new ArgumentNullException("p");

        _persons.Add(p);
        DoSideAffect();
    }
}

public class GroupRepository
{
    public Group FindBy(Criteria c)
    {
        // Use whatever technology (EF, NHibernate, ADO.NET, etc) to retrieve the data

        var group = new Group(new Collection<Person>(listOfPersonsFromDataStore));

        return group;
    }

    public void Save(Group g)
    {
        // Use whatever technology to save the group
        // Iterate through g.Persons to persist membership information if needed
    }
}

使用依赖注入框架(Spring.NET,MEF,Unity等)并创建一个IGroupRepository接口,该接口可以在您的应用程序代码中注入,以检索和保留您的组域对象。

答案 1 :(得分:0)

缺乏属性不是一个显示阻碍; XmlSerializer有一个构造函数可以在运行时传递这个模型(但说实话,大多数情况下默认值都很好) - 就像其他几个序列化程序一样。如果可读性是一个问题,那么通过XmlSerializer显然需要XML。见XmlAttributeOverrides。我还可以建议一些可以在这里工作的二进制序列化器。