首页 > 解决方案 > 将 Autofac 开放通用接口注册转换为 DryIoc 注册

问题描述

我想从 github 注册一个中介 Im 使用,它提供了一个使用 Autofac 注册它的示例。

我认为我的问题在于这条 Autofac 行:

builder.RegisterAssemblyTypes(assembly)
    .AsClosedTypesOf(typeof(IMessageHandler<,>))
    .AsImplementedInterfaces();

AsClosedTypesOf更具体地说,我不是 100% 确定代码行的作用。

我试图将其翻译为 DryIoc:

container.RegisterMany(
    new Type[] { typeof(IMessageHandler<,>) },
    serviceTypeCondition: s => s.IsInterface, 
    setup: Setup.With(openResolutionScope: true));

但我收到以下错误:

DryIoc.ContainerException: '注册抽象实现类型 SimpleMediator.Core.IMessageHandler<,> 当它应该是具体的。也没有可以使用的 FactoryMethod。

到目前为止,这是我的注册码:

        container.RegisterMany(
            new Type[] { typeof(IMessageHandler<,>) },
            serviceTypeCondition: s => s.IsInterface, 
            setup: Setup.With(openResolutionScope: true));

        //var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic);
        container.RegisterDelegate<ServiceFactoryDelegate>(c => t =>
        {
            return c.Resolve(t);
        });

        container.RegisterMany<ServiceFactory>();
        container.RegisterMany<Mediator>();
        container.RegisterMany(new Type[] { typeof(MessageProcessor<,>) });

        container.Register<IService1, Service1>(Reuse.Singleton);
        container.Register<IService2, Service2>(Reuse.Singleton);

        var service1 = container.Resolve<IService1>();
        var service2 = container.Resolve<IService2>();

        service1.GetDevice("asdf");

没有对 IMessageHandler 接口使用 RegisterMany 程序会遇到错误:

System.ArgumentException:“没有为 DeviceEventMessage Arg_ParamName_Name 找到签名 IMessageHandler`2 的处理程序”

基本上我的理解是我需要注册我定义的消息处理程序,它继承自IMessageHandler<,>

Mediator 将 IMessageHandler 定义为:

public interface IEventHandler<in TEvent>
    : IMessageHandler<TEvent, Unit> where TEvent : IMessage<Unit>
{
}

我在服务中实现它:

public class Service2 : IService2, IEventHandler<DeviceEventMessage>
{
    public async Task<Unit> HandleAsync(
        DeviceEventMessage message,
        IMediationContext mediationContext,
        CancellationToken cancellationToken)
    {
        return Unit.Result;
    }
}

其中 service1 实际上调用了GetDevice("asdf")需要解析处理程序的中介。

我将如何注册IMessageHandler<,>DryIoc中实现的类?

标签: c#dependency-injectionautofacdryioc

解决方案


更新:修复了工作样本

添加s.GetGenericDefinitionOrNull()serviceTypeCondition

回答

例外正是这里的问题:

container.RegisterMany(
    new Type[] { typeof(IMessageHandler<,>) },
    serviceTypeCondition: s => s.IsInterface,
    setup: Setup.With(openResolutionScope: true));

RegisterMany重载期望第一个参数是具体实现类型的集合。

对于您的情况,您可能需要这样的东西:

container.RegisterMany(
    new[] { typeof(Service1).GetAssembly() },
    serviceTypeCondition: s => s.GetGenericDefinitionOrNull() == typeof(IMessageHandler<,>));

顺便说一句,不知道是什么原因openResolutionScope: true


推荐阅读