如何在ASP中注入泛型的依赖.净的核心
本文关键字:依赖 核心 泛型 注入 ASP | 更新日期: 2023-09-27 18:05:32
我有以下存储库类:
public class TestRepository : Repository<Test>
{
private TestContext _context;
public TestRepository(TestContext context) : base(context)
{
_context = context;
}
}
public abstract class Repository<T> : IRepository<T> where T : Entity
{
private TestContext _context;
public Repository(TestContext context)
{
_context = context;
}
...
}
public interface IRepository<T>
{
...
}
如何在ASP中实现依赖注入?. NET Core in my Startup.cs
?
我是这样实现的:
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
但是我得到以下错误:
无法实例化实现类型"Test.Domain.Repository
1[T]' for service type 'Test.Domain.IRepository
1[T]"。
Repository<T>
是一个抽象类,所以你不能将它注册为一个实现,因为抽象类根本不能被实例化。如果Repository<T>
不是抽象的,您的注册将正常工作。
如果您不能使存储库类非抽象,您可以注册您的存储库类的特定实现:
services.AddScoped(typeof(IRepository<Test>), typeof(TestRepository));
我知道这很晚了,但我在这里张贴我的解决方案,以便其他人可以参考和使用它。我写了一些扩展来注册泛型接口的所有派生类型。
public static List<TypeInfo> GetTypesAssignableTo(this Assembly assembly, Type compareType)
{
var typeInfoList = assembly.DefinedTypes.Where(x => x.IsClass
&& !x.IsAbstract
&& x != compareType
&& x.GetInterfaces()
.Any(i => i.IsGenericType
&& i.GetGenericTypeDefinition() == compareType))?.ToList();
return typeInfoList;
}
public static void AddClassesAsImplementedInterface(
this IServiceCollection services,
Assembly assembly,
Type compareType,
ServiceLifetime lifetime = ServiceLifetime.Scoped)
{
assembly.GetTypesAssignableTo(compareType).ForEach((type) =>
{
foreach (var implementedInterface in type.ImplementedInterfaces)
{
switch (lifetime)
{
case ServiceLifetime.Scoped:
services.AddScoped(implementedInterface, type);
break;
case ServiceLifetime.Singleton:
services.AddSingleton(implementedInterface, type);
break;
case ServiceLifetime.Transient:
services.AddTransient(implementedInterface, type);
break;
}
}
});
}
在启动类中,你只需像下面这样注册你的通用接口。
services.AddClassesAsImplementedInterface(Assembly.GetEntryAssembly(), typeof(IRepository<>));
您可以在这个Github存储库中找到完整的扩展代码。
抽象类只能注册为服务,不能注册为实现。
参见下面的定义
public abstract class BaseClass<T>
{
public BaseClass()
{
}
}
public class DerivedClass : BaseClass<Entity>
{
public DerivedClass() : base() { }
}
public class DerivedClass2<T> : BaseClass<T> where T: Entity
{
}
public class Entity
{
}
控制器:
public class WeatherForecastController : ControllerBase
{
......
public WeatherForecastController(BaseClass<Entity> baseClass)
{
}
...
}
如果你以这种方式注入它们:
services.AddScoped(typeof(BaseClass<>), typeof(DerivedClass));
当你解决依赖时,你会得到这个错误:
开放泛型服务类型'BaseClass ' 1[T]'需要注册一个开放泛型实现类型。(参数描述符)
你应该注册泛型类型,或者用定义的泛型参数注册服务和实现
现在这个应该也可以正常工作了
services.AddScoped(typeof(BaseClass<>), typeof(DerivedClass2<>));
或
services.AddScoped(typeof(BaseClass<Entity>), typeof(DerivedClass2<Entity>));
我更喜欢接口定义,而不是抽象类。