这是我从具体抽象基类派生的具体存储库
public class DepartmentRepository : RepositoryBase<Department>, IDepartmentRepository
public abstract class RepositoryBase<T> : IRepository<T> where T : class, IPersistantBusinessObject
这是我的界面
public interface IDepartmentRepository : IRepository<Department>
public interface IRepository<T> where T : IPersistantBusinessObject
public interface IPersistantBusinessObject { ... }
这是我的实体
public class Department : BusinessObjectBase
public abstract class BusinessObjectBase : IPersistantBusinessObject
如何将我的DepartmentRepository转换为通用IRepository?
DepartmentRepository rep = new DepartmentRepository();
(IRepository<IPersistentBusinessObject>)rep; // this doesn't work
想法?如果你想知道,这是一个使用存储库模式的asp.net MVC3应用程序。我是否过度构建接口?我现在想如何使用通用存储库?
感谢。
编辑: 这是我的IRepository界面。当被问及为什么我需要转换为IRepository时,实际上我只能使用“SaveChanges”方法,因为我想拦截数据库中的任何异常并以通用方式处理。
public interface IRepository<T> where T: IPersistantBusinessObject
{
IQueryable<T> Retrieve();
T Retrieve(int id);
IQueryable<T> RetrieveActiveAndInActive();
T RetrieveActiveAndInActive(int id);
void Add(T domainObject);
void SaveChanges();
void Delete(T domainObject);
void Delete(int id)
}
答案 0 :(得分:3)
你想在这做什么?我想不出你想要投射到IRepository<IPersistentBusinessObject>
的情况。什么代码依赖于什么抽象?
我通常希望其他代码依赖于IDepartmentRepository
的抽象,并且根本无法真正看到IRepository<T>
甚至IPersistentBusinessObject
的用例。同样,如果您可以找到依赖于该抽象的代码的用例,那么它们是有价值的;否则,YAGNI。
(顺便说一句,这是测试驱动开发很有价值的一个原因。你可以通过编写单元测试来确定需要哪些抽象,并查看需要模拟哪些类来隔离某些功能的测试,而不是只是模糊地将所有东西抽象成接口,因为你被告知它们比具体类型更好。从具体类型开始,当你的测试强制你提取界面时,那是正确的时间!)
但实际上,这是covariance of generic types的问题。如果你说
,它应该有效public interface IRepository<out T> where T : IPersistantBusinessObject
答案 1 :(得分:0)
您需要将其投射到IRepository<Department>
。
DepartmentRepository
派生自实现RepositoryBase<Department>
的{{1}}。
您可能需要查看co and contravariance ...
答案 2 :(得分:0)
正如Daniel暗示的那样,你不能把它强制转换为IRepository,因为你已经将IRepository接口定义为只与另一个类型T一起存在。所以“IRepository”作为接口不存在。
如果您希望能够使用“IRepository”接口,那么它需要是一个没有类型依赖的独立接口。
也许您需要两个接口,一个用于实现IRepository中所需的基本功能,另一个用于实现类型T的泛型方法。 e.g。
<!-- language: lang-c# -->
public interface IRepository
{
SaveChanges()
...
}
public interface IRepositoryFor<T> where T : IPersistantBusinessObject
{
T GetFirst(); // or whatever
...
}