Как зарегистрировать ServiceHelper для каждого IService в Autofac ContainerBuilder? - PullRequest
0 голосов
/ 06 мая 2019

Я создаю удобный вспомогательный пакет DI, который бы добавлял простую однофункциональную регистрацию компонентов (в духе .AddEntityFramework() -подобных методов), чтобы соответствовать моему основному пакету.

По сутипользователи библиотеки зарегистрируют один или несколько IService (singleton) экземпляров, а затем вызовут мой метод RegisterServiceHelpers().

. Я хочу, чтобы метод регистрировал помощника для каждого IService зарегистрированного пользователя,Пример метода (не работает)

public static void RegisterServiceHelpers(this ContainerBuilder self)
{
    foreach (var service in self.Build().Resolve<IEnumerable<IService>>())
        self.Register(c =>
            new ServiceHelper(service)).SingleInstance();
}

Это невозможно, поскольку Autofac разрешает вызывать .Build() только один раз.

Также я попытался использовать поддержку неявного списка, подобную этой

self.Register(c => c.Resolve<IEnumerable<MessageBusFactory>>()
    .Select(factory =>
        new RabbitMqHealthCheckHandler(
            factory,
            c.Resolve<ILogger<RabbitMqHealthCheckHandler>>())))
        .SingleInstance()
    .As<IEnumerable<IHealthCheckHandler>>();

Но это не работает, не говоря уже о неправильной области действия SingleInstance()

1 Ответ

2 голосов
/ 06 мая 2019

Метод AttachToComponentRegistration модуля позволяет добавлять динамическую регистрацию.

class XModule : Module
{
    protected override void AttachToComponentRegistration(
        IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        base.AttachToComponentRegistration(componentRegistry, registration);

        if (registration.Services.OfType<IServiceWithType>()
            .Any(s => s.ServiceType == typeof(IService)))
        {
            IComponentRegistration r = RegistrationBuilder
                .ForType<ServiceHelper>()
                .WithParameter(
                    (pi, c) => pi.ParameterType == typeof(IService),
                    (pi, c) => c.ResolveComponent(
                        registration, Enumerable.Empty<Parameter>()))
                .SingleInstance()
                .CreateRegistration();

            componentRegistry.Register(r);
        }
    }
}

Тогда вы можете зарегистрировать свой модуль как builder.RegisterModule<XModule>()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...