[英]Autofac - resolve open generic type to resolve to derived type
我正在尝试使用 autofac 注册开放泛型类型以解析为派生类型
public interface IBackGroundJobHandler<T> where T: INotification
{
public Task Handle(T notification, CancellationToken cancellationToken);
}
public abstract class EventHandler<T> : IBackGroundJobHandler<T> where T : INotification
{
public abstract Task Handle(T notification, CancellationToken cancellationToken);
}
public class TestEventHandler : EventHandler<TestEvent>
{
public async override Task Handle(TestEvent notification, CancellationToken
cancellationToken)
{
await Task.Delay(20000);
System.Diagnostics.Debug.WriteLine("Test Event Finished");
}
}
public class SomeService<T> where T:INotfication
{
public SomeService(IBackGroundJobHandler<T> handler)
{
//sometask
}
}
我尝试通过以下方式注册:
builder.RegisterGeneric(typeof(EventHandler<>)).As(typeof(IBackGroundJobHandler<>))
.InstancePerLifetimeScope();
IBackgroundJobHandler 未在服务构造函数中解析。
我也试过:
builder.RegisterAssemblyTypes(typeof(EventHandler).GetTypeInfo().Assembly)
.AsClosedTypesOf(typeof(IBackGroundJobHandler<>)).InstancePerLifetimeScope();
我是 autofac 的新手,我该如何解决这个问题?
我避免了抽象 class 并简单地使用了通用接口 IBackGroundJobHandler<>
public class TestEventHandler : IBackGroundJobHandler<TestEvent>
{
public async override Task Handle(TestEvent notification, CancellationToken
cancellationToken)
{
//Task
}
}
在 Autofac 容器中注册为:
builder.RegisterAssemblyTypes(typeof(IBackGroundEventHandler<>)
.GetTypeInfo().Assembly)
.AsClosedTypesOf(typeof(IBackGroundEventHandler<>))
.InstancePerLifetimeScope()
.AsImplementedInterfaces();
EventHandler<T> 是一个抽象的 class,因此 Autofac 解析器将无法创建一个。
您还没有注册 TestEventHandler(例如),所以 Autofac 不知道它。
当您请求 IBackGroundJobHandler<TestEvent> 时,我假设您想要解析 TestEventHandler,但 class 尚未注册。
因此,鉴于您需要注册 TestEventHandler,您可能根本不需要 EventHandler<T> 抽象 class。 (我猜你认为这将是一种注册所有派生自 EventHandler<T> 的类的方法)。 TestEventHandler 可以只实现 IBackGroundJobHandler<TestEvent>。
class TestEventHandler : IBackGroundJobHandler<TestEvent>
{
public async Task Handle(TestEvent notification, CancellationToken cancellationToken)
{
// Process the Test Event
}
}
然后使用:
builder.RegisterType<TestEventHandler>()
.As<IBackGroundJobHandler<TestEvent>>()
.InstancePerLifetimeScope();
如果你有很多事件处理程序,这可能会很痛苦,所以我会使用反射来查找实现接口的类:
// Get the assembly that contains the implementors, assuming
// they are all in the same assembly as the TestEventHandler:
Assembly assembly = typeof(TestEventHandler).Assembly;
// Get all classes from assembly that implement the required interface
Type[] classesThatImplementIBackGroundJobHandler = assembly.GetTypes()
.Where(t => t.IsClass
&& t.GetInterfaces().Any(i =>
i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IBackGroundJobHandler<>).GetGenericTypeDefinition())).ToArray();
// Register All Types that Implement our interface
builder.RegisterTypes(classesThatImplementIBackGrounJobHandler)
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.