2

我是 NServiceBus 的新手,正在努力使用结构映射在我的控制器中注入 IBus。实际上,在做了一些研究之后,我发现我们可以通过将以下代码放入 global.asax 的 Application_Start 事件中来注入它 -

protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        Configure.With()
                 .Log4Net()
                 .StructureMapBuilder()
                 .XmlSerializer()
                 .MsmqTransport()
                 .IsTransactional(false)
                 .PurgeOnStartup(false)
                 .UnicastBus()
                 .ImpersonateSender(false)
                 .CreateBus();
    }

在我的控制器中,我可以使用 IBus 作为属性或构造函数注入:

private IBus Bus { get; set; }
    private ITest Test { get; set; }

    public MyLinkController(IBus bus, ITest test)
    {
        Bus = bus;
        Test = test;
    }

这工作正常并且注入总线没有任何问题。但我的问题是我无法控制 global.asax,所以我想将配置放在其他地方,例如我尝试将其放在结构映射注册表中,如下所示:

For<IBus>().Use(
            () =>
                NServiceBus.Configure.With()
                                         .Log4Net()
                                         .StructureMapBuilder()
                                         .XmlSerializer()
                                         .IsTransactional(true)
                                         .PurgeOnStartup(false)
                                         .UnicastBus()
                                         .ImpersonateSender(false)
                                         .CreateBus()
                                         .Start()
                );

但这无济于事。看起来结构映射需要在自己初始化之前知道配置。那么没有 application_start 事件有什么办法吗?

4

1 回答 1

3

我能够通过结构图本身来做到这一点。这就是我更改结构映射注册表的方式:

public ServiceBusRegistry()
    {
        ForSingletonOf<IBus>().Use(
            NServiceBus.Configure.With()
                       .Log4Net()
                       .DefaultBuilder()
                       .XmlSerializer()
                       .MsmqTransport()
                       .IsTransactional(false)
                       .PurgeOnStartup(false)
                       .UnicastBus()
                       .ImpersonateSender(false)
                       .CreateBus()
                       .Start()
            );
    }

将其放入结构映射的 Registry 类中后,我可以在我的控制器中注入 IBus:

public MyController(IRepository<Test, int> repository, IBus bus)
    {
        _repository = repository;
        _bus = bus;
    }

注意,这里我使用 DefaultBuilder 而不是 StructureMapBuilder。我将来可能会尝试进一步改进它,但到目前为止它对我来说工作正常。

更新(在我们的项目设计更改后):

现在我们的 API 项目中有一个启动类(该项目是 ASP.NET Web API)虽然我们不使用 global.asax 的 Application_start,但我们可以将启动代码放在这个启动类中:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(WebApiPreStartup), "Start", Order = -999)] //make sure we are first

namespace ADP.DS.FrontOffice.Quoting.WebApi
{
    public static class WebApiPreStartup
    {
        public static void Start()
        {
            GlobalFilterConfig.Configure(GlobalConfiguration.Configuration);
            BusConfig.Init();
        }
    }
}

并且配置在单独的类中:

public static void Init()
    {
        Configure.Serialization.SystemXml();
        Configure.ScaleOut(s => s.UseSingleBrokerQueue());
        var configUnicastBus = Configure.With()
            .StructureMapBuilder(ObjectFactory.Container)
            .UseTransport<NServiceBus.RabbitMQ>()
            .PurgeOnStartup(false)
            .UnicastBus();
        configUnicastBus.SendOnly();
    }
于 2013-01-15T11:02:57.853 回答