无法在.NET Core中注册嵌套的通用接口 [英] Cannot register nested generic interface in .NET Core
问题描述
我正在尝试在DI容器中注册嵌套的泛型类型,但无法注册
I am trying to register the nested generic type in DI container, but unable to register
抛出{开放的泛型服务类型需要注册开放的泛型实现类型。 (参数描述符)}错误
throws {Open generic service type requires registering an open generic implementation type. (Parameter descriptors)} error
实现的接口方法如下:
public class CustomerEvent<TEntity> : IEventConsumer<EntityInsertedEvent<TEntity>>,
IEventConsumer<EntityUpdatedEvent<TEntity>>,
IEventConsumer<EntityDeletedEvent<TEntity>> where TEntity : BaseEntity
{
public void HandleEvent(EntityInsertedEvent<TEntity> eventMessage)
{
throw new NotImplementedException("Inserted");
}
public void HandleEvent(EntityUpdatedEvent<TEntity> eventMessage)
{
throw new NotImplementedException("Updated");
}
public void HandleEvent(EntityDeletedEvent<TEntity> eventMessage)
{
throw new NotImplementedException("Deleted");
}
}
尝试
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(item => item.GetInterfaces()
.Where(i => i.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(IEventConsumer<>))
&& !item.IsAbstract && !item.IsInterface)
.ToList().ForEach(assignedTypes =>
{
assignedTypes.GetInterfaces()
.Where(i => i.GetGenericTypeDefinition() == typeof(IEventConsumer<>)).ToList()
.ForEach(imp =>
{
services.AddScoped(imp, assignedTypes);
});
});
但失败
推荐答案
没有简单的方法可以做到这一点。通常,您需要将开放通用的抽象映射到开放通用的实现,例如:
There is no easy way to do this. Typically, you need to map an open-generic abstraction to an open-generic implementation, like this:
services.AddTransient(typeof(IEventConsumer<>), typeof(CustomerEvent<>));
但是,这在您的情况下不起作用,因为MS.DI无法弄清楚该类的泛型类型参数如何 IEventCustomer< T>
应该映射到 CustomerEvent< TEntity>
的通用类型参数。例如,在解析 IEventCustomer< EntityInsertedEvent< Order>>
时,它将尝试创建 CustomerEvent< EntityInsertedEvent< Order>>
,尽管它应该已经创建了 CustomerEvent< Order>
。
This, however, will not work in your case because MS.DI is unable to figure out how the generic type argument for IEventCustomer<T>
should maps to the generic type argument of CustomerEvent<TEntity>
. When resolving an IEventCustomer<EntityInsertedEvent<Order>>
, for instance, it will try to create a CustomerEvent<EntityInsertedEvent<Order>>
, while it should have been creating a CustomerEvent<Order>
.
这不是.NET的限制或CLR,但是它是MS.DI DI容器特有的限制,因为其他一些DI容器实际上能够进行此类映射。
This is not a limitation of .NET or the CLR, but a limitation that is specific to the MS.DI DI Container, because some other DI Containers are actually able to make these kinds of mappings.
不幸的是,使用MS.DI ,没有简单的出路。您唯一可以做的就是显式地进行所有可能的封闭通用注册,例如:
Unfortunately, with MS.DI, there is no easy way out. The only thing you can do is making all possible closed-generic registrations explicitly, e.g.:
s.AddTransient<IEventConsumer<EntityInsertedEvent<Order>>, CustomerEvent<Order>>();
s.AddTransient<IEventConsumer<EntityInsertedEvent<Customer>>, CustomerEvent<Customer>>();
s.AddTransient<IEventConsumer<EntityInsertedEvent<Product>>, CustomerEvent<Product>>();
s.AddTransient<IEventConsumer<EntityInsertedEvent<Employee>>, CustomerEvent<Employee>>();
s.AddTransient<IEventConsumer<EntityInsertedEvent<etc>>, CustomerEvent<etc>>();
这篇关于无法在.NET Core中注册嵌套的通用接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!