使用NServicebus实现Autofac的鸡肉和鸡蛋问题

时间:2017-01-19 10:50:57

标签: c# .net inversion-of-control autofac 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();
}

RegisterNServiceBusWithAutofac

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行上收到以下错误:

  

无法设置密钥的值:   NServiceBus.AutofacBuilder + LifetimeScopeHolder。设置已经   锁定修改。移动前面的任何配置代码   配置管道

我认为这意味着

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

但是

我不能这样做,因为我需要将endpointinstance注册到IoC,因为我需要在我的控制器中发送消息。而这还不存在,因为我首先需要endpointConfiguration

所以我有鸡蛋和鸡蛋的情况......

问题

  

我是否正确理解了这个问题,我该如何解决呢?   确保IoC适用于Controller?

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

1 个答案:

答案 0 :(得分:1)

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

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

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