我完全混淆了自己试图设计必要的接口和摘要来完成域实体的加载,这些域实体可以单独使用,也可以组合成聚合。哇。那是一句流行语。本质上,我有两个对象,我希望有基本类型“加载”功能,但当这两个对象合并为一个时,我会遇到多重继承。
所以,我有我的实体,就像这样(我画了
public class Account
public class Document
public class AccountDocument
{
public Account Account{get;set;}
public Document Document{get;set;}
}
然后,我有接口,像这样:
public interface IAccountRepository
{
Account Load(IDataContext context);
}
public interface IDocumentRepository
{
Document Load(IDataContext context);
}
public interface IAccountDocumentRepository
{
AccountDocument Load(IDataContext context);
}
由于Account和Document都可以(并且是)从其他实体派生,我想在实现中提供基本功能,以便我遵循DRY。
public abstract class AccountRepositoryBase : IAccountRepository
{
Account Load(IDataContext context)
{
//implementation for loading the Account from the context
}
}
public abstract class DocumentRepositoryBase : IDocumentRepository
{
Document Load(IDataContext context)
{
//implementation for loading the Document from the context
}
}
这适用于个人帐户和文档对象及其派生,但我似乎无法解决的问题是如何处理AccountDocument ......
public class AccountDocumentRepository : AccountRepositoryBase, DocumentRepositoryBase
{
//This is not possible, of course, due to multiple inheritance.
}
我知道解决方案不会那么难,但我完全纠缠不清,无法理解如何只提供一次基本“加载”功能。请帮忙!
提前致谢。
答案 0 :(得分:2)
您可以使用组合而不是实现继承来解决这个问题 - 只需让AccountDocumentRepository
委托给您已编写的存储库类:
public class AccountDocumentRepository : IAccountDocumentRepository
{
IAccountRepository accountRepository = new AccountRepositoryBase();
IDocumentRepository documentRepository = new DocumentRepositoryBase();
public AccountDocument Load(IDataContext context) {
Document document = this.documentRepository.Load(context);
Account account = this.accountRepository.Load(context);
return new AccountDocument(account, document);
}
}
如果您希望灵活地替换不同的具体存储库,则可以提供一个或多个构造函数,以便客户端代码注入IAccountRepository
和IDocumentRepository
。
有几个很好的StackOverflow问题讨论了实现继承和组合的相对优点,并解释了为什么我们应该更喜欢组合。这些只是搜索“作品继承”的一小部分结果。
答案 1 :(得分:1)
您不希望AccountDocumentRepository
实施IAccountDocumentRepository
,而不是继承AccountRepositoryBase
和DocumentRepositoryBase
吗?
然后,您始终可以将AccountRepositoryBase
和DocumentRepositoryBase
属性添加到IAccountDocumentRepository
界面,或将它们添加到AccountDocumentRepository
的构造函数中,以确保您拥有两者的实例工作。
public class AccountDocumentRepository : IAccountDocumentRepository
{
public AccountDocumentRepository(AccountRepositoryBase account, DocumentRepositoryBase document)
{
this.account = account;
this.document = document;
}
public AccountDocument Load(IDataContext context)
{
//use your account & document instances here to create an AccountDocument.
}
}
答案 2 :(得分:0)
您可能希望从“企业应用程序架构模式”一书中查看继承映射器模式。
然后基于它创建自己的继承存储库模式。
请参阅: