Как получить сеанс / конечную точку сообщения с общим хостом?

Я использую несколько конечных точек NServiceBus, созданных с использованием общей конфигурации хоста (https://docs.particular.net/samples/hosting/generic-host/). Эти конечные точки работают в контейнерах Docker. Теперь я хочу запланировать сообщение (с зависанием). Всякий раз, когда выполняется запланированное сообщение, я получаю следующую ошибку:

Value cannot be null. (Parameter 'session')

System.ArgumentNullException: Value cannot be null. (Parameter 'session')
   at NServiceBus.Guard.AgainstNull(String argumentName, Object value)
   at NServiceBus.IMessageSessionExtensions.Send(IMessageSession session, Object message)
   at Provisioning.Handlers.CustomerCreatedHandler.Reauthenticate(Guid customerId) in /src/Provisioning/Handlers/CustomerCreatedHandler.cs:line 30

Это связано с тем, что метод Send() не имеет сеанса сообщений. Однако как мне получить эту сессию? На https://docs.particular.net/nservicebus/hosting/ вы можете создать сеанс, запустив новую конечную точку из EndpointConfiguration. Поскольку я использую общий хост, у меня есть только EndpointConfiguration, но у меня нет доступа к конечной точке, созданной из этого (или, по крайней мере, я не знаю, как это сделать). Вот как выглядит моя конфигурация (очень упрощенная):

hostBuilder = Host.CreateDefaultBuilder()
    .UseConsoleLifetime()
    .UseNServiceBus(xtc =>
    {
        var endpointConfiguration = new EndpointConfiguration("endpointName");
        endpointConfiguration.UseSerialization<NewtonsoftSerializer>();
        endpointConfiguration.EnableInstallers();
        endpointConfiguration.DefineCriticalErrorAction(OnCriticalError);

        // removed all config

        return endpointConfiguration;
    });

И это начинается с:

await hostBuilder.Build().RunAsync();

Кстати, я использую NServiceBus 7.

Редактировать:

Вот как я планирую задачу Hangfire (обновлено на основе ответа Шимона, но еще не работает):

public class CustomerCreatedHandler : IHandleMessages<CustomerCreated>
{
    private static IServiceProvider _provider;

    public CustomerCreatedHandler(IServiceProvider provider)
    {
        _provider = provider;
    }

    public async Task Handle(CustomerCreated message, IMessageHandlerContext context)
    {
        RecurringJob.AddOrUpdate($"Reauthenticate-{message.CustomerId}", () => Reauthenticate(message.CustomerId), Cron.Hourly);
    }

    public static Task Reauthenticate(Guid customerId)
    {
        IMessageSession session = _provider.GetService<IMessageSession>();
        return session.Send(new AuthenticateCustomer { CustomerId = customerId });
    }
}

Это приводит к:

System.ArgumentNullException
Value cannot be null. (Parameter 'provider')

System.ArgumentNullException: Value cannot be null. (Parameter 'provider')
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Provisioning.Handlers.CustomerCreatedHandler.Reauthenticate(Guid customerId) in /src/Provisioning/Handlers/CustomerCreatedHandler.cs:line 33

1 ответ

Вы можете решить IMessageSession из IServiceProviderкак показано здесь в фоновом работнике.

Другие вопросы по тегам