Autofac украшает открытые дженерики, зарегистрированные с использованием сканирования сборки - PullRequest
5 голосов
/ 15 ноября 2011

Я пытаюсь применить к моему сценарию функцию поддержки автоматического декоратора, но безуспешно.Похоже, в моем случае он не назначает имя для регистрации должным образом.

Есть ли способ зарегистрировать отсканированные типы сборок с именем, чтобы впоследствии я мог использовать его в открытом универсальном ключе декоратора?

Или, может быть, я совершенно не прав и делаю здесь что-то неуместное?

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 ]

13 голосов
/ 16 ноября 2011

Вот попытка, не перед 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;
3 голосов
/ 20 сентября 2013

Если вы хотите очистить свой регистрационный код, вы также можете определить следующий дополнительный метод расширения (очень подробный и основанный на источнике автофака для другой перегрузки, но его нужно определить только один раз):

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();
...