使用 autofac 注册命名类型并使用字符串参数的名称

Registering a named type with autofac and using the name for string parameter

我有以下注册(请注意,我还没有完成这段代码,所以它甚至可能无法按预期工作):

builder.RegisterType<SimpleInMemoryChannel>()
    .Named<IChannel>("ErrorChannel")
    .WithParameter(new NamedParameter("channelName", "ErrorChannel"));
builder.RegisterType<SimpleInMemoryChannel>()
    .Named<IChannel>("RequestCbrInput")
    .WithParameter(new NamedParameter("channelName", "RequestCbrInput"));

// Constructor: public SimpleInMemoryChannel(string channelName)

如您所见,我正在尝试使用已注册对象的名称作为 channelName 值。代码有点冗长。有什么办法可以让分配自动发生吗?例如我只想写:

builder.RegisterType<SimpleInMemoryChannel>()
    .Named<IChannel>("ErrorChannel");
builder.RegisterType<SimpleInMemoryChannel>()
    .Named<IChannel>("RequestCbrInput");

并自动设置频道名称。

默认功能中没有允许这种情况发生的任何内容。您将需要自定义您的注册,或者使用工厂进行解析。最简单的解决方案是您在评论中提到的那个 - 添加一个用于注册频道的辅助函数 - 这样您仍然可以使用默认的解析过程。

使用 RegisterChannel 方法可能是更优雅的解决方案。

顺便说一句,如果你没有这样的方法,你可以使用自定义模块:

public class NamedParameterModule<TServiceType> : Module
{
    private readonly string _parameterName;

    public NamedParameterModule(String parameterName)
    {
        this._parameterName = parameterName;
    }

    protected override void AttachToComponentRegistration(
        IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        KeyedService keyedService = registration.Services
            .OfType<KeyedService>()
            .FirstOrDefault(ks => ks.ServiceType == typeof(TServiceType));

        if (keyedService != null)
        {
            registration.Preparing += (sender, e) =>
            {
                e.Parameters = e.Parameters.Concat(new Parameter[] { 
                    new NamedParameter(this._parameterName, keyedService.ServiceKey)
                });
            };
        }

        base.AttachToComponentRegistration(componentRegistry, registration);
    }
}

并使用builder.RegisterModule(new NamedParameterModule<IFoo>("channelName"));

注册

这个 dotnetfiddle 的实例:https://dotnetfiddle.net/MPfMup.