How to inject dependencies of generics in ASP.NET Core
I know this is very late but I am posting my solution here so that others can refer and use this. I have written some extensions to register all the derived types of generic interface.
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;
}
}
});
}
In the startup class, you just register your generic interface like below.
services.AddClassesAsImplementedInterface(Assembly.GetEntryAssembly(), typeof(IRepository<>));
You can find the complete extension code in this Github repository.
Repository<T>
is an abstract class, so you cannot register it as an implementation, because abstract class simply cannot be instantiated. Your registration would work fine if Repository<T>
was not abstract.
If you cannot make repository class non-abstract, you can register specific implementation of your repository class:
services.AddScoped(typeof(IRepository<Test>), typeof(TestRepository));
This will correctly inject dependencies to your controller.