I'm new to the Dependency Injection in ASP.NET Core 3.1, and I'm trying to create Singleton instances of my Repository classes using Reflection, but I can't get it to work.
Currently, the BookService
uses the BookRepository
from the DI:
public class BookService : IBookService
{
private readonly IBookRepository _bookRepository;
public BookService(IBookRepository bookRepository)
{
_bookRepository = bookRepository;
}
public async Task<Book> GetById(string id)
{
var find = await _bookRepository.FindAsync(id);
return find;
}
}
It works because I added a singleton service to the container, with the following code ( link to Microsoft Docs ): services.AddSingleton<IBookRepository, BookRepository>();
I'm trying to achieve the same result using Reflection.
BookRepository
public class BookRepository : BaseRepository<Book>, IBookRepository
{
}
IBookRepository
public interface IBookRepository : IAsyncRepository<Book>
{
}
This is what I have so far:
// Get all classes implementing IAsyncRepository
var repositoryTypes = assembly.GetTypes()
.Where(x => !x.IsInterface
&& x.GetInterface(typeof(IAsyncRepository<>).Name) != null);
foreach (var repositoryType in repositoryTypes)
{
// Adds a singleton service of BookRepository
services.AddSingleton(repositoryType);
}
But as you can see, the code above is adding only the BookRepository
, missing to reference the IBookRepository
interface, so it's throwing the following error:
System.ArgumentException: 'Cannot instantiate implementation type 'IBookRepository' for service type 'IBookRepository'.'
Do you know how can I do that?
**EDIT:** This is the implementation I made to solve the problem:
``` c#
public static class DependencyInjectionExtensions
{
public static void AddApplicationServices(
this IServiceCollection services)
{
var assembly = Assembly.GetExecutingAssembly();
RegisterImplementationsOfServiceType(
services, assembly, typeof(IService));
RegisterImplementationsOfServiceType(
services, assembly, typeof(IAsyncRepository<>));
}
private static void RegisterImplementationsOfServiceType(
IServiceCollection services, Assembly assembly, Type type)
{
var implementationsType = assembly.GetTypes()
.Where(x => !x.IsInterface && x.GetInterface(type.Name) != null);
foreach (var implementationType in implementationsType)
{
var servicesType = implementationType.GetInterfaces()
.Where(r => !r.Name.Contains(type.Name));
foreach (var serviceType in servicesType)
{
services.AddSingleton(serviceType, implementationType);
}
}
}
}
Something like this would work
// Get all classes implementing IAsyncRepository
var repositoryTypes = assembly.GetTypes().Where(x => !x.IsInterface &&
x.GetInterface(typeof(IAsyncRepository<>).Name) != null);
foreach (var repositoryType in repositoryTypes)
{
var type = repositoryType.UnderlyingSystemType;
services.AddSingleton(type.GetInterface($"I{type.Name}"), type);
}
I'm not sure if there is a better way to get the interface type
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.