我们正在尝试找出使用 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 列表。 DomainEntityAs 可以独立存在,但是 DomainEntityB 不能在没有 DomainEntityAs 列表的情况下存在
我们如何加载 DomainEntityB 中的 DomainEntityA 项目列表并维护 DomainEntityA 的所有逻辑。
在 DomainEntityBService 中重用 DomainEntityAService?
在 DomainEntityBService 中创建一个单独的 DomainEntityARepository?
我们目前使用 EntLib,但正在寻找更多关于设计的信息,然后是 DAL 实现。
最佳答案
要不你改用一个让你插入类型的通用接口(interface)怎么样?像这样:
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 上写了很多文章在我的博客上,所以如果你想了解更多,可以去那里。
关于c# - 存储库和服务设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2313163/