Регистрация зависимостей в NServiceBus с помощью Autofa c после обновления - PullRequest
0 голосов
/ 21 февраля 2020

У меня возникла проблема при разработке способа регистрации зависимостей в моей конечной точке NServiceBus. Я использую NServiceBus 7.2 и Autofa c 5.0 и NServiceBus.Autofa c 7.0.0 и не могу найти никаких примеров, которые используют эти версии. Я использую Asp. Net Core 3.

Мой код Program.cs выглядит следующим образом

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Мой метод ConfigureServices выглядит следующим образом

   public void ConfigureServices(IServiceCollection services)
        {

            services.InstallServicesInAssembly(Configuration);
            services.AddAutoMapper(typeof(Startup));
            services.AddMediatR(typeof(Startup).Assembly);

        }

Это запускает все установщики, которые у меня есть, но запускает ДО метода ConfigureContainer, вызываемого платформой. AutoFa c автоматически добавляет все службы, которые были добавлены в COnfigureServices. У меня есть отдельный класс для каждого установщика. Мой метод ConfigureContainer в настоящее время пуст, поскольку службы Automapper и MediatR все равно добавляются, поскольку службы добавляются в ConfigureServices. Это разрешает IMediatR и IMapper, когда они вводятся в контроллеры Api. Но они не доступны в обработчиках сообщений NServiceBus. Это потому, что я не вижу, как зарегистрировать конфигурацию конечной точки или предоставить общий доступ к контейнеру Autofa c после его создания. См. Комментарий к коду установщика NServiceBus ниже.

 //here we register stuff directly with autofac
    public void ConfigureContainer(ContainerBuilder builder)
    {
        // Register your own things directly with Autofac, like:

        //builder.AddAutoMapper(typeof(Startup).Assembly);
       // builder.AddMediatR(typeof(Startup).Assembly);
    }

Я хочу иметь возможность использовать AutoMapper и MediatR в моих обработчиках сообщений NServiceBus и поэтому хочу, чтобы эти зависимости были внедрены в конструкторы обработчиков.

И мой NServiceBusInstaller выглядит следующим образом

public class NServiceBusInstaller : IInstaller
{
    public async void InstallServices(IServiceCollection services, IConfiguration configuration)
    {
        var rabbitMQSettings = new RabbitMQSettings();
        configuration.Bind(nameof(rabbitMQSettings), rabbitMQSettings);
        services.AddSingleton(rabbitMQSettings);

        var endpointConfiguration = new EndpointConfiguration(rabbitMQSettings.SilvaDirectory);
        endpointConfiguration.EnableInstallers();

        //Here I want to configure the endpoint to use the dependencies in the AutoFac container
        //How to get reference to this container??

        /*
        endpointConfiguration.UseContainer<AutofacBuilder>(
           customizations: customizations => {
               customizations.ExistingLifetimeScope(container);
           });
        */

        var transport = endpointConfiguration.UseTransport<RabbitMQTransport>();
        transport.UseConventionalRoutingTopology();
        transport.ConnectionString(rabbitMQSettings.ConnectionString);
        transport.TimeToWaitBeforeTriggeringCircuitBreaker(TimeSpan.FromMinutes(1));


        //services.AddNServiceBus(endpointConfiguration);

        await Endpoint.Start(endpointConfiguration).ConfigureAwait(false);


    }
}

И, наконец, один из моих обработчиков сообщений выглядит следующим образом. В настоящее время я получаю исключение, потому что NServiceBus не может разрешить IMapper и IMediator.

public class CreateDirectoryEntryHandler : IHandleMessages<CreateDirectoryEntry>
{
    private readonly IMapper _mapper;
    private readonly IMediator _mediator;
    public CreateDirectoryEntryHandler(IMapper mapper, IMediator mediator)
    {
        _mapper = mapper;
        _mediator = mediator;
    }
    public async Task Handle(CreateDirectoryEntry message, IMessageHandlerContext context)
    {

        var command = _mapper.Map<CreateNewCustomerCommand>(message);
        CommandResponse response = await _mediator.Send(command);

        if(response.Success)
        {
            await context.Reply(new DirectoryEntryCreated() { Email = message.Email }).ConfigureAwait(false);
        }
        else
        {
            await context.Reply(new DirectoryEntryRejected() { Email = message.Email, Error = response.Error }).ConfigureAwait(false);
        }

    }
}

Возможно, мне не хватает чего-то очевидного. Мой умственный блок заключается в том, что метод ConfigureContainer вызывается после метода служб Configure средой, поэтому у меня нет ссылки на контейнер для передачи установщику NServiceBus. Что мне не хватает? Любая помощь будет принята с благодарностью. Спасибо

1 Ответ

0 голосов
/ 25 февраля 2020

вы можете посмотреть на этот образец https://docs.particular.net/samples/dependency-injection/aspnetcore/. В нем показано, как использовать Asp. Net Core 3 с NServiceBus и Autofa c.

. В своем примере кода вы используете endpointConfiguration.UseContainer<AutofacBuilder>() API, который предполагает, что его NServiceBus контролирует жизненный цикл DI. контейнер. Это явно не тот случай.

В примере используются пакеты NServiceBus.Extensions.Hosting и Autofa c .Extensions.DependencyInjection . Во-первых, убедитесь, что NServiceBus может работать с DI-контейнером, который управляется извне через Microsoft.Extensions.Hosting , а второй - адаптер Autofa c для абстракций Microsoft DI.

...