我们正在尝试找出使用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的大量文章,因此如果您想了解更多信息,可以去那里。