. net Core中带有继承和泛型的依赖注入



我有以下最小的、可重复的示例:

public class BaseEntity{}    
public class BaseChildClass: BaseEntity{}    
public class ChildA : BaseChildClass {}
public class ChildB : BaseChildClass {}
public interface IRepository<TEntity> where TEntity : BaseEntity{}
public class DataRepository<TEntity> : IRepository<TEntity>
where TEntity : BaseEntity{}
public class Program
{
public static void Main()
{
var services = new ServiceCollection();
if (ChildAFeature) // loaded from config
{
services.AddScoped<IRepository<BaseChildClass>, DataRepository<ChildA>>();
}
else
{
services.AddScoped<IRepository<BaseChildClass>, DataRepository<ChildB>>();
}
var provider = services.BuildServiceProvider();

var service = provider.GetService<BaseChildClass>();

Console.WriteLine(service.GetType());
}
}

问题是当尝试像这样注入服务时:

services.AddScoped<IRepository<BaseChildClass>, DataRepository<ChildA>>();

编译错误显示

没有从DataRepository来IRepository

我需要根据特性标志注入ChildAChildB到存储库。所以基本上,有时我需要childda repo,有时根据条件需要childdb repo。

您的服务注册方式错误。

更新了你的。net提琴提琴链接。

这是注册泛型依赖的方法。

public static void Main()
{
var services = new ServiceCollection();
services.AddScoped(typeof(IRepository<>), typeof(DataRepository<>));
services.AddScoped<BaseChildClass, ChildA>();
var provider = services.BuildServiceProvider();

var repo = provider.GetService<IRepository<ChildA>>();
Console.WriteLine(repo.GetType());

var service = provider.GetService<BaseChildClass>();

Console.WriteLine(service.GetType());
}

泛型形参不能真正用于继承。

然而,你可以在接口中将T声明为<out T>,那么你的用例应该可以工作。然而,这确实迫使您只使用T作为返回值,而不是作为输入值。您可以看看IEnumerable<T>是如何声明的,它也是这样做的。

最新更新