使用 NServicebus 实现 Autofac 的先有鸡还是先有蛋问题

Chicken and egg issue implementing Autofac with NServicebus

背景

我正在尝试设置需要与 NServicebus 端点通信的 Web API 2。

我需要实现 IoC,这将使用 Autofac 完成。

我有什么

控制器定义如下:

[RoutePrefix("api")]
public class Controller : ApiController
{
    private IEndpointInstance EndpointInstance { get; set; }

    public public MyController(IEndpointInstance endpointInstance)
    {
        this.EndpointInstance = endpointInstance;
    }

    [HttpGet]
    [Route("dostuff")]
    public async Task DoStuff()
    {
        var command = new MyCommand
        {
            ...
        };

        await this.EndpointInstance.SendLocal(command);
    }
}

并在global.asax

Application_Start

protected async void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);

    await RegisterNServiceBusWithAutofac();
}

注册NServiceBusWithAutofac

private async Task RegisterNServiceBusWithAutofac()
{
    var builder = new ContainerBuilder();

    var endpointConfiguration = await GetEndpointConfiguration("My.Service");

    var endpointInstance = await Endpoint.Start(endpointConfiguration);

    builder.RegisterInstance(endpointInstance);

    var container = builder.Build();

    endpointConfiguration.UseContainer<AutofacBuilder>(c => c.ExistingLifetimeScope(container));

    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
}

GetEndpointConfiguration

private static async Task<EndpointConfiguration> GetEndpointConfiguration(string name)
{
    var endpointConfiguration = new EndpointConfiguration(name);

    // Set transport.
    var routing = endpointConfiguration.UseTransport<MsmqTransport>().Routing();

    // Register publish to self
    routing.RegisterPublisher(typeof(EventHasFinished), name);

    endpointConfiguration.UseSerialization<JsonSerializer>();
    endpointConfiguration.UsePersistence<InMemoryPersistence>();
    endpointConfiguration.SendFailedMessagesTo("error");
    endpointConfiguration.EnableInstallers();

    return endpointConfiguration;
}

结果

我在 UseContainer 行收到以下错误:

Unable to set the value for key: NServiceBus.AutofacBuilder+LifetimeScopeHolder. The settings has been locked for modifications. Move any configuration code earlier in the configuration pipeline

我认为这是什么意思

认为 我需要在创建 endpointConfiguration 时为 NServicebus 进行所有 Autofac 注册。之后上面操作了构建器实例。

但是

我不能执行上述操作,因为我需要将 endpointinstance 注册到 IoC,因为我需要在我的控制器中发送消息。那还不存在,因为我首先需要 endpointConfiguration

所以我有先有鸡还是先有蛋的情况...

问题

Do I understand the issue correctly and how can I solve it while making sure that IoC works correctly for the Controller?

即:this.EndpointInstance 已通过 IoC 正确实例化。

您可以使用 lambda 表达式注册它,而不是注册 actual 实例,该表达式将在第一次要求容器解析时执行 IEndpointInstance.

builder
    .Register(x =>
    {
        var endpointConfiguration = GetEndpointConfiguration("My.Service").GetAwaiter().GetResult();
        var endpointInstance = Endpoint.Start(endpointConfiguration).GetAwaiter().GetResult();

        return endpointInstance
    })
    .As<IEndpointInstance>()
    .SingleInstance();