AUTOFAC-解决开放的通用类型以解决派生类型

发布于 2025-02-06 04:15:13 字数 1312 浏览 1 评论 0原文

我正在尝试使用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的新手,该如何解决?

I am trying to use autofac to register open generic type to resolve to derived type

   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
  }
 }

 

I tried registering it by :

        builder.RegisterGeneric(typeof(EventHandler<>)).As(typeof(IBackGroundJobHandler<>))
        .InstancePerLifetimeScope();

IBackgroundJobHandler is not resolving in service constructor.

I also tried:

 builder.RegisterAssemblyTypes(typeof(EventHandler).GetTypeInfo().Assembly)    
.AsClosedTypesOf(typeof(IBackGroundJobHandler<>)).InstancePerLifetimeScope();

I am new to autofac, how can I resolve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

意中人 2025-02-13 04:15:13

我避免了抽象类,并简单地使用了通用接口ibackgroundJobhandler&lt;&gt;

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();

I avoided abstract class and simply used generic interface IBackGroundJobHandler<>

public class TestEventHandler : IBackGroundJobHandler<TestEvent>
{
   public async override Task Handle(TestEvent notification, CancellationToken 
   cancellationToken)
 {
    //Task

 }
}

Registered in Autofac container as:

builder.RegisterAssemblyTypes(typeof(IBackGroundEventHandler<>)
.GetTypeInfo().Assembly)                
.AsClosedTypesOf(typeof(IBackGroundEventHandler<>))
.InstancePerLifetimeScope()
.AsImplementedInterfaces();
墨小沫ゞ 2025-02-13 04:15:13

EventHandler&lt; t&gt;是一个抽象类,因此AUTOFAC解析器无论如何都无法创建。

您尚未注册testeventhandler(例如),因此AutoFac不了解它。

当您要求ibackgroundJobhandler&lt; testevent&gt;我假设您想解决一个testeventhandler,但是尚未注册该课程。

因此,鉴于您需要注册testeventhandler,您可能不需要eventhandler&lt; t&gt;无论如何,抽象类。 (我猜您认为这将是注册从EventHandler&lt; t&gt; in Go中派生的所有类的一种方式)。 TestEventHandler可以实现IbackgroundJobhandler&lt; testevent&gt;。

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();
      
    .

EventHandler<T> is an abstract class, so the Autofac resolver will not be able to create one anyway.

You've not registered TestEventHandler (for example), so Autofac is unaware of it.

When you request a IBackGroundJobHandler<TestEvent>, I presume that you want to get a TestEventHandler resolved, but that class has not been registered.

So, given that you need to register TestEventHandler, you probably don't need that EventHandler<T> abstract class anyway. (I'm guessing that you thought that would be a way of registering all classes that derived from EventHandler<T> in on go). The TestEventHandler can just implement IBackGroundJobHandler<TestEvent>.

class TestEventHandler : IBackGroundJobHandler<TestEvent>
{
    public async Task Handle(TestEvent notification, CancellationToken cancellationToken)
    {
         // Process the Test Event
    }
}

Then use:

builder.RegisterType<TestEventHandler>()
    .As<IBackGroundJobHandler<TestEvent>>()
    .InstancePerLifetimeScope();

If you have many event handlers, it can be a pain, so I'd use reflection to find the classes that do implement the interface:

// 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();
      
    .
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文