我们正在尝试找出使用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 e.g。
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列表。 DomainEntityAs可以独立生存,但DomainEntityB不能没有DomainEntityAs列表
我们如何加载DomainEntityB中的DomainEntityA项列表并维护DomainEntityA的所有逻辑。
在DomainEntityBService中重用DomainEntityAService?
在DomainEntityBService中创建一个单独的DomainEntityARepository?
我们目前使用的是EntLib,但是正在查看有关设计的信息,然后是DAL实现。
答案 0 :(得分:0)
我在这里假设您将要存储到数据库中。
对此的答案很大程度上取决于您使用的持久性引擎。如果您手动滚动自己的持久性,则C
不是一个选项,因为您将看到N + 1个查询。 B
很可能是我的第一选择,因为它提供了最多的代码重用,希望是非常糟糕的性能。
说过如果你使用像NHibernate这样的东西,我建议你不要使用存储库模式而是
我希望这有帮助!
答案 1 :(得分:0)
您如何使用允许您插入类型的通用界面?像这样:
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的大量文章,所以如果你想了解更多,你可以去那里。