У меня возникла проблема при разработке способа регистрации зависимостей в моей конечной точке 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. Что мне не хватает? Любая помощь будет принята с благодарностью. Спасибо