Asp.net mvc 4 使用不带global.asax的structuremap注入NServiceBus

Asp.net mvc 4 使用不带global.asax的structuremap注入NServiceBus,asp.net-mvc-4,dependency-injection,asp.net-web-api,structuremap,nservicebus,Asp.net Mvc 4,Dependency Injection,Asp.net Web Api,Structuremap,Nservicebus,我不熟悉NServiceBus,正在努力使用结构图在控制器中注入IBus。实际上,在做了一点研究之后,我发现我们可以通过在global.asax的Application_Start事件中添加以下代码来注入它- protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.F

我不熟悉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,因此我想将配置放在其他地方,例如,我尝试将其放在structuremap注册表中,如下所示:

For<IBus>().Use(
            () =>
                NServiceBus.Configure.With()
                                         .Log4Net()
                                         .StructureMapBuilder()
                                         .XmlSerializer()
                                         .IsTransactional(true)
                                         .PurgeOnStartup(false)
                                         .UnicastBus()
                                         .ImpersonateSender(false)
                                         .CreateBus()
                                         .Start()
                );
For()。使用(
() =>
NServiceBus.Configure.With()
.Log4Net()
.StructureMapBuilder()
.XmlSerializer()
.IsTransaction(真)
.PurgeOnStartup(错误)
.UnicastBus()
.ImpersonateSender(错误)
.CreateBus()
.Start()
);
但这没用。看起来结构映射需要在自己初始化之前知道配置。
那么,没有应用程序启动事件,有什么方法可以做到这一点呢?

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

public ServiceBusRegistry()
    {
        ForSingletonOf<IBus>().Use(
            NServiceBus.Configure.With()
                       .Log4Net()
                       .DefaultBuilder()
                       .XmlSerializer()
                       .MsmqTransport()
                       .IsTransactional(false)
                       .PurgeOnStartup(false)
                       .UnicastBus()
                       .ImpersonateSender(false)
                       .CreateBus()
                       .Start()
            );
    }
配置在单独的类中:

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();
    }
publicstaticvoidinit()
{
Configure.Serialization.SystemXml();
Configure.ScaleOut(s=>s.UseSingleBrokerQueue());
var configUnicastBus=Configure.With()
.StructureMapBuilder(ObjectFactory.Container)
.UseTransport()
.PurgeOnStartup(错误)
.UnicastBus();
configUnicastBus.SendOnly();
}

您能再解释一下关于无法控制global.asax的问题吗?您必须在应用程序_Start中进行调用才能配置StructureMap。如果此调用位于单独的类(甚至是静态方法)中,您可以在引导容器之前配置总线。实际上,我们正在构建单独的模块,这些模块将集成到一个公共项目中,例如“a”。现在,由于结构图对所有模块都是通用的,所以我们将其保留在“A”中。但是我们不能把NServiceBus放在那里,因为它是特定于一个模块的。您对这个实现做了任何更改吗?@JoshC。是的,我们多次重构它,因为我们的项目结构/设计一直在变化。我在回答时更新了当前的方法。不过,如果你想找别的东西,如果你能解释一下,我可以试着帮你。谢谢,但我想我会改用MassTransit。
[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();
    }