我如何使用通用dbset <t>的依赖注入

时间:2017-10-13 13:54:36

标签: c# generics dependency-injection interface .net-core

我有一个接口,我希望用它来执行有效性检查,就像将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

1 个答案:

答案 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)选项。你看到代码在演示中编译得很好。