我有一个接口,我希望用它来执行有效性检查,就像将id传递给方法一样简单,它应该返回true或false,无论该实体是否存在。我不想为我的每个存储库都有这个实现,所以我创建了一个单独的接口IValidityCheck<T> where T: DbSet<T>
,如下所示。
public interface IValidityCheck<T> where T: DbSet<T>
{
bool IsValid(Guid id, T entitySet);
}
现在在我的.net核心应用程序中,我正在尝试为此添加依赖项。我有类似的东西。
services.AddTransient<IValidityCheck<DbSet<School>>, ValidityCheck<DbSet<School>>>();
但是我收到了像
这样的错误类型 'Microsoft.EntityFrameworkCore.DbSet' 不能在泛型类型或方法中用作类型参数“T” 'IValidityCheck'。没有隐式引用转换 'Microsoft.EntityFrameworkCore.DbSet' 至 'Microsoft.EntityFrameworkCore.DbSet&GT;'
我知道将其更改为约束where T: class
会更容易,但我希望约束特定于DbSet
答案 0 :(得分:3)
您有两个选择:
1)您可能还需要一个参数。像这样:
public interface IValidityCheck<T, I> where T: DbSet<I>
并像这样使用它:
services.AddTransient<IValidityCheck<DbSet<School>, School>, ValidityCheck<DbSet<School>,School>>();
2)另一种可能性是你可以通过引入另一个接口来抽象出DbSet:
public interface IValidityCheckBase<T> where T: class
{
bool IsValid(Guid id, T entitySet);
}
public interface IValidityCheck<T> : IValidityCheckBase<DbSet<T>>
{
}
您的示例通用实现:
public class ValidityCheck<T> : IValidityCheck<T>
{
public bool IsValid(Guid id, DbSet<T> entitySet)
{
return false;
}
}
然后它应该工作,甚至没有在你的泛型类型用法中声明DbSet,因为你想强制它为DbSet,这应该更简洁:
services.AddTransient<IValidityCheck<School>, ValidityCheck<School>>();
在此DEMO中,我使用List<T>
代替,但它应该相似。我个人喜欢2)选项。你看到代码在演示中编译得很好。