Asp.net mvc 4 使用不带global.asax的structuremap注入NServiceBus
我不熟悉NServiceBus,正在努力使用结构图在控制器中注入IBus。实际上,在做了一点研究之后,我发现我们可以通过在global.asax的Application_Start事件中添加以下代码来注入它-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
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();
}