Autofac украшает открытые дженерики, зарегистрированные с использованием сканирования сборки
Я пытаюсь применить функцию поддержки авто декоратора к моему сценарию, но безуспешно. Похоже, в моем случае он не назначает имя для регистрации должным образом.
Есть ли способ зарегистрировать отсканированные типы сборок с именем, чтобы впоследствии я мог использовать его в открытом универсальном ключе декоратора?
Или, может быть, я совершенно не прав и делаю что-то неуместное здесь?
builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly)
.AsClosedTypesOf(typeof(IAggregateViewRepository<>)) //here I need name, probably
.Named("view-implementor", typeof(IAggregateViewRepository<>))
.SingleInstance();
builder.RegisterGenericDecorator(typeof(CachedAggregateViewRepository<>),
typeof(IAggregateViewRepository<>), fromKey: "view-implementor");
2 ответа
Вот попытка, не перед Visual Studio, поэтому разрешение перегрузки может быть не совсем правильным:
builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly)
.As(t => t.GetInterfaces()
.Where(i => i.IsClosedTypeOf(typeof(IAggregateViewRepository<>))
.Select(i => new KeyedService("view-implementor", i))
.Cast<Service>())
.SingleInstance();
Named()
это просто синтаксический сахар дляKeyed()
, который связывает компонент сKeyedService
As()
принимаетFunc<Type, IEnumerable<Service>>
Вам также понадобится:
using Autofac;
using Autofac.Core;
Если вы хотите очистить свой регистрационный код, вы также можете определить следующий дополнительный метод расширения (очень подробный и основанный на источнике autofac для другой перегрузки, но его нужно определить только один раз):
using Autofac;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Features.Scanning;
public static class AutoFacExtensions
{
public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle>
AsClosedTypesOf<TLimit, TScanningActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration,
Type openGenericServiceType,
object key)
where TScanningActivatorData : ScanningActivatorData
{
if (openGenericServiceType == null) throw new ArgumentNullException("openGenericServiceType");
return registration.As(t =>
new[] { t }
.Concat(t.GetInterfaces())
.Where(i => i.IsClosedTypeOf(openGenericServiceType))
.Select(i => new KeyedService(key, i)));
}
}
Это позволит вам просто сделать это:
builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly)
.AsClosedTypesOf(typeof(IAggregateViewRepository<>), "view-implementor")
.SingleInstance();