我大约有100个存储库类,它们都实现相同的接口。它们都有共同的依赖性。
我已经用不同的名称注册了这个常见依赖的两个版本。
我想使用命名的依赖项第二次注册我所有的存储库类。
这基本上是我的原始注册内容:
builder.RegisterAssemblyTypes(typeof(Repository<>).Assembly)
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IClientContext),
(pi, ctx) => ctx.ResolveNamed<IClientContext>(RegistrationKeys.Published)))
.AsImplementedInterfaces();
因此,如果我想使用不同的密钥第二次注册所有相同的类型,则需要执行以下操作:
builder.RegisterAssemblyTypes(typeof(Repository<>).Assembly)
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IClientContext),
(pi, ctx) => ctx.ResolveNamed<IClientContext>(RegistrationKeys.Unpublished)))
.Named(RegistrationKeys.Unpublished)
.AsImplementedInterfaces();
但是,这是行不通的,因为Named方法需要指定注册的类型,但是它应该基于RegisterAssemblyTypes调用中的一系列解析类型而为动态。
如何在不向应用程序中添加数百行代码的情况下做到这一点?
答案 0 :(得分:1)
您也许可以编写自己的扩展方法来完成此操作。
具有功能的.Named
中的You might have noticed that there is an overload:
builder.RegisterAssemblyTypes(typeof(AComponent).GetTypeInfo().Assembly)
.Named(t => t.Name, typeof(object));
该函数接受Type
在程序集中的注册,并使用该类型在服务上生成名称。不幸的是,该重载也仅将特定的固定类型用作服务类型,因此这会将所有内容注册为Named<object>(...)
,这不是您想要的。
但是!
If you look at how that's implemented ...
public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle>
Named<TLimit, TScanningActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration,
Func<Type, string> serviceNameMapping,
Type serviceType)
where TScanningActivatorData : ScanningActivatorData
{
return registration.As(t => new KeyedService(serviceNameMapping(t), serviceType));
}
...您可以看到基本上是将类型注册,然后将其传递给您提供的函数以生成该名称。您可以将其更改为 not 而不接受特定的服务类型,然后将其注册为自己。
public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle>
NamedSelf<TLimit, TScanningActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration,
Func<Type, string> serviceNameMapping)
where TScanningActivatorData : ScanningActivatorData
{
return registration.As(t => new KeyedService(serviceNameMapping(t), t));
}
现在使用您自定义的NamedSelf
扩展名。
builder.RegisterAssemblyTypes(typeof(Repository<>).Assembly)
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IClientContext),
(pi, ctx) => ctx.ResolveNamed<IClientContext>(RegistrationKeys.Unpublished)))
.NamedSelf(t => RegistrationKeys.Unpublished)
.AsImplementedInterfaces();
您当然可以根据需要进行更新。也许您不希望它成为一个函数,而只是接受一个字符串-很简单。也许您希望将其注册为命名接口-您可以让函数生成整个KeyedService
而不是将其嵌入扩展名中。
要点是,您可以使用现有扩展名作为灵感来编写自己的自定义扩展名,这些扩展名可以满足您的需求,而不必手动注册。
[免责声明:除了我的主意之外,我没有通过编译器来运行所有这些操作,因此可能存在拼写错误,导致无法复制/粘贴。您还需要检查null参数和所有其他内容。单击链接以查看实际的原始资源。希望这至少可以解除您的封锁。]