繁体   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