我们正在尝试找出使用DDD时的最佳实践,并且我们正在讨论什么才是最有意义的方法或“正确方法”。

注意:所有代码均为伪代码。

允许以下内容:

public interface IDomainEntityAService
{
    void CreateMyObject(DomainEntityA myobject);
    DomainEntityA RetrieveDomainEntityA(long someId);
    //Other operations that handle the business logic dealing with MyObject
}


我们还有另一个服务,该服务使用IDomainEntityAService的某些部分来满足特殊需求。

public interface IDomainEntityBService
{
    DomainEntityB GetDomainEntityB();
}


其中OtherInformation包含以下内容:

public class DomainEntityB
{
    public string Name { get; set; }
    public IList<DomainEntityA> DomainEntityAList { get; set; }
}


现在是我们的问题。我们正在研究使用存储库来持久保存OtherInformation,如下所示:

public interface IDomainEntityBRepository
{
    void Add(DomainEntityB information);
    DomainEntityB Get(long someId);
}


由于我们希望将所有内容保持为DRY,因此理想情况下,我们希望重用IDomainEntityAService的逻辑来检索DomainEntityB的DomainEntityAList列表。哪一个最有意义?

A)在IDomainEntityBRepository中有对IDomainEntityAService的引用
例如

public class SqlDomainEntityBRepository : IDomainEntityBRepository
{

    public SqlDomainEntityBRepository(IDomainEntityAService domainEntityAService, Database database)
    {

    }

    public void Add(DomainEntityB information)
    {
        //save DomainEntityB to SQL
    }
    public DomainEntityB Get(long someId)
    {
        //Get OtherInformation.Name from SQL
        //use domainEntityAService.Get() to populate the list of DomainEntityAList
        //return DomainEntityB
    }
}


B)IDomainEntityBRepository仅处理SQL内容,我们使用IHaveOtherInformation的服务层填充MyObjects列表

public class DomainEntityBService : IDomainEntityBService
{
    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {
        var domainEntityB = _repo.Get(someId);
        domainEntityB.DomainEntityAList = _domainEntityAService.GetAll(someId);
        return domainEntityB;
    }
}


C)我们为OtherInformation创建一个特定的DAL对象,并使用服务层组成OtherInformation的实例

public class DomainEntityBDAL
{
    public string Name { get; set; }
    public IList<int> DomainEntityAListIds { get; set; }
}


然后,我们将有一个存储库来检索OtherInformationDAL,然后代码如下所示:

public class DomainEntityBService : IDomainEntityBService
{

    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo)
    {
    }
    public DomainEntityB GetDomainEntityB()
    {

        var domainEntityBDAL = _repo.Get(someId);
        DomainEntityB result = new DomainEntityB() { Name = domainEntityBDAL.Name };
        foreach (var id in domainEntityBDAL.DomainEntityAListIds)
        {
            result.DomainEntityAList.Add(_domainEntityAService.Get(id));
        }
        return result;
    }
}


D)哇,我们完全没有根据,而是这样做!!!

我希望这是有道理的,感谢您的帮助。

编辑注释:

也许英文说明可以帮助更好地描述我的问题。我们有DomainEntityA,它是一个聚合根。有一个相应的服务来处理与DomainEntityA有关的所有逻辑。

现在,我们还有DomainEntityB,它是一个聚合根。但是,DomainEntityB具有DomainEntityAs的列表。 DomainEntityA可以自己生存,但是DomainEntityB不能没有DomainEntityAs列表生存

我们如何在DomainEntityB中加载DomainEntityA项目列表,并维护DomainEntityA的所有逻辑。

在DomainEntityBService中重用DomainEntityAService吗?
在DomainEntityBService中创建一个单独的DomainEntityARepository吗?

我们目前使用EntLib,但我们希望获得更多有关设计的信息,而不是DAL实现。

最佳答案

取而代之的是使用可插入类型的通用界面呢?像这样:

public interface IRepository<T>
{
    T Get(object id);
    void Save(T value);
    void Update(T value);
    void Delete(T value);
    IList<T> GetAll();
}


无论使用哪种实现,都应该能够读取类型并知道其如何适合数据库。简而言之,这就是存储库模式。如果您尚未完全设置Entlib,请探索NHibernate。我发现它很好地补充了存储库模式。我已经在我的博客上关于this topic的大量文章,因此如果您想了解更多信息,可以去那里。

07-27 21:52