【问题标题】:How do i use dependency injection with generic dbset<T>如何将依赖注入与通用 dbset<T> 一起使用
【发布时间】:2018-03-25 16:30:40
【问题描述】:

我有一个我希望用来执行有效性检查的接口,就像将一个 id 传递给一个方法一样简单,无论该实体是否存在,它都应该返回 true 或 false。我不想为我的每个存储库都有这个实现,所以我创建了一个单独的接口IValidityCheck&lt;T&gt; where T: DbSet&lt;T&gt;,如下所示。

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>'

我知道将其更改为 where T: class 的约束会更容易,但我希望约束特定于 DbSet

【问题讨论】:

  • 怎么可能是 DbSet?我认为您需要另一个通用变量
  • 你的定义就像一个无限递归循环。 public interface IValidityCheck&lt;T, I&gt; where T: DbSet&lt;I&gt;services.AddTransient&lt;IValidityCheck&lt;DbSet&lt;School&gt;, School&gt;, ValidityCheck&lt;DbSet&lt;School&gt;,School&gt;&gt;(); 怎么样

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


【解决方案1】:

你有两个选择:

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&lt;T&gt;,但应该是类似的。我个人喜欢 2) 选项。您会看到代码在演示中编译得很好。

【讨论】:

    猜你喜欢
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    相关资源
    最近更新 更多