这可能是之前提出的,但我无法解决这个问题。也许如果我能得到正确的头衔,我可以贬低它。
我有这个通用存储库接口:
public interface IRepository<TEntity>
{
TEntity Resolve<TEntity>(); // dummy function, just to get the idea
}
我还有一个通用的工作单元,它能够解析通用存储库:
public interface IUnitOfWork
{
IRepository<TEntity> GetGenericRepository<TEntity>() where TEntity : class;
}
到目前为止一切顺利。
但是随着现实生活的继续,我想创建一个自定义存储库,其中包含一些特定的功能。所以我在想:继承;像这样:
public class SpecialRepository : IRepository<SomeEntityType>
{
public void SomeSpecialFunction() { };
}
显然,使用GetGenericRepository
方法无法解析此类型,所以我想:让我们为IUnitOfWork
接口添加一个额外的方法:
public interface IUnitOfWork
{
//same old get generic repository
IRepository<TEntity> GetGenericRepository<TEntity>() where TEntity : class;
//the newly added.
T GetInheretedRepository<T>() where T : class;
}
我希望能够使用特殊存储库调用工作单元,如下所示:
public test()
{
IUnitOfWork uow = new UnitOfWork();
//I want to make this call with a constraint on TemplateRepo
//to enforce it's type: IRepository<T> (which TemplateRepo is)
var y = uow.GetInheretedRepository<TemplateRepo>();
}
问题是:如何将T
中的T GetInheretedRepository<T>() where T : class;
类型限制为类型:IRepository<TEntity>
?
我试过了:
public interface IUnitOfWork
{
//the newly added.
//error: Only class or interface could be specified as constraint
T GetInheretedRepository<T>() where T : class, IRepository; }
和
public interface IUnitOfWork
{
//the newly added.
//error: type argument missing
T GetInheretedRepository<T>() where T : class, IRepository<>;
}
不起作用。
我可以放弃约束作为快速修复或者可能创建一个继承的工作单元,但随后;问题仍然存在。
答案 0 :(得分:2)
执行此操作的方法是添加第二个泛型类型参数,如下所示:
TRepository GetInheretedRepository<TRepository, TEntity>()
where TRepository : IRepository<TEntity>
where TEntity : class;
这里提供存储库类型和实体类型。这样C#编译器就可以检查类型是否匹配。以下是如何调用它:
var rep = uow.GetInheretedRepository<SpecialRepository, SomeEntityType>();
rep.SomeSpecialFunction();
这显然很糟糕,因为你必须指定这两种类型。但更重要的是,这很糟糕,因为您必须指定具体类型,使您的代码依赖于具体类型;违反了Dependency Inversion Principle。
我真的想建议您远离一个依赖于具体类型的设计,甚至更好,远离那些在特定存储库类上有许多方法的设计,因为这违反了{{{ 3}},SRP和OCP这可能会在以后导致维护问题。
相反,请查看ISP中描述的应用程序设计。
答案 1 :(得分:1)
您需要指定第二个类型
public interface IUnitOfWork
{
//the newly added.
T GetInheretedRepository<T, TEntity>() where T : class, IRepository<TEntity>;
}
public interface IRepository<TEntity>
{
TEntity Resolve(); // dummy function, just to get the idea
}
编译好的示例 - https://dotnetfiddle.net/MmmPil