如何在ASP中使用自己的接口注册多个实现.. NET Core使用反射?



我是ASP依赖注入的新手。. NET Core 3.1,我试图使用反射创建我的存储库类的单例实例,但我不能让它工作。

当前BookService使用DI的BookRepository:

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;
}
}

它的工作,因为我添加了一个单例服务的容器,与以下代码(链接到微软文档):services.AddSingleton<IBookRepository, BookRepository>();

我正在尝试使用反射实现相同的结果。

BookRepository

public class BookRepository : BaseRepository<Book>, IBookRepository
{
}

IBookRepository

public interface IBookRepository : IAsyncRepository<Book>
{
}

这是我目前为止写的:

// 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);
}
但是正如您所看到的,上面的代码只添加了BookRepository,没有引用IBookRepository接口,因此它抛出了以下错误:

系统。ArgumentException: '无法为服务类型'IBookRepository'实例化实现类型'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);
}
}
}
}

这样就可以了

// 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);
}

我不确定是否有更好的方法来获得接口类型

最新更新