簡體   English   中英

Autofac - 解析開放泛型類型以解析為派生類型

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM