Pal*_*lmi 8 c# generics dependency-injection asp.net-core
我有以下存储库类:
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>
{
...
}
Run Code Online (Sandbox Code Playgroud)
如何在我的ASP.NET Core中实现依赖注入Startup.cs
?
我这样实现了:
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
Run Code Online (Sandbox Code Playgroud)
但后来我得到以下错误:
无法实例化实现类型'Test.Domain.Repository
1[T]' for service type 'Test.Domain.IRepository
1 [T]'.
dot*_*tom 17
Repository<T>
是一个抽象类,因此您无法将其注册为实现,因为抽象类根本无法实例化.如果Repository<T>
不是抽象的,您的注册将正常工作.
如果您不能使存储库类非抽象,则可以注册存储库类的特定实现:
services.AddScoped(typeof(IRepository<Test>), typeof(TestRepository));
Run Code Online (Sandbox Code Playgroud)
这将正确地将依赖项注入您的控制器.
小智 7
我知道这已经很晚了,但我在这里发布了我的解决方案,以便其他人可以参考和使用它。我编写了一些扩展来注册泛型接口的所有派生类型。
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;
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
在启动类中,您只需注册您的通用接口,如下所示。
services.AddClassesAsImplementedInterface(Assembly.GetEntryAssembly(), typeof(IRepository<>));
Run Code Online (Sandbox Code Playgroud)
您可以在此Github存储库中找到完整的扩展代码。
归档时间: |
|
查看次数: |
8137 次 |
最近记录: |