使用 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.
我有以下注册(请注意,我还没有完成这段代码,所以它甚至可能无法按预期工作):
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.