首页 > 解决方案 > 是否可以使用 Autofac 程序集扫描为多个键注册一种类型?

问题描述

我正在尝试MyClass在 AutoFac 中注册多个键(即 3、4、5)的类型(即)。所以, componentContext.ResolveKeyed<T>(3),componentContext.ResolveKeyed<T>(4)componentContext.ResolveKeyed<T>(5)所有返回MyClass实例。我不确定如何根据Keyed<IMyClass>()类型而不是值来执行此操作。

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
            .Where(type => type.IsAssignableTo<IMyClass>())
            .Keyed<IMyClass>(type => type.GetCustomAttribute<MyCustomAttribute>().VALUES)
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();

[MyCustomAttribute(3, 4, 5)]
class MyClass : IMyClass { }

class MyCustomAttribute : Attribute {
    public int[] VALUES { get; set; }

    public MyCustomAttribute(params int[] values) {
       this.Values = values;
    }
}

标签: c#dependency-injectionautofac

解决方案


这在 Autofac 核心中不受支持,但您可以轻松地创建一个扩展方法来为您完成它。

public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle>
    Keyed<TService>(
        this IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle> registration,
        Func<Type, object[]> serviceKeyMapping)
{
    var serviceType = typeof(TService);
    return registration
        .AssignableTo(serviceType)
        .As(t => serviceKeyMapping(t).Select(key => new KeyedService(key, serviceType)));
}

它应该大致可以替代您正在尝试做的事情。

通过使用现有的扩展方法作为许多工作示例的起点,Autofac 很容易以这种方式进行扩展。我放在这里的是对现有Keyed<T>程序集扫描扩展的一个非常小的修改。由于不可能涵盖每个用例,因此这是填补此类空白的“官方解决方案”。


推荐阅读