[英]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.