Lor*_*nzo 3 asp.net-mvc simple-injector rebus azure-servicebus-queues
设置:在 asp.net mvc 项目中使用 SimpleInjector 进行 Rebus。
我需要创建两个接收消息的处理程序,每个处理程序来自一个特定的队列。按照我在这个SO 答案中找到的内容,我创建了类似的代码。
在一个类库中,我有一个实现 SimpleInjector 的类,IPackage它的代码如下:
public void RegisterServices( Container container ) {
container.Register<IHandleMessages<MyMessage>, MyMessageHandler>( Lifestyle.Scoped );
IContainerAdapter adapter = new SimpleInjectorContainerAdapter( container );
Configure.With( adapter )
.Transport( t => t.UseAzureServiceBus( connectionString, "A_QUEUE_NAME", AzureServiceBusMode.Standard ) )
.Options( oc => {
oc.SetNumberOfWorkers( 1 );
oc.SimpleRetryStrategy( errorQueueAddress: "A_ERROR_QUEUE_NAME", maxDeliveryAttempts: 3 );
} )
.Start();
Configure.With(adapter
.Transport(t => t.UseAzureServiceBus(connectionString, "B_QUEUE_NAME")
.Options( oc => {
oc.SetNumberOfWorkers( 1 );
oc.SimpleRetryStrategy( errorQueueAddress: "B_ERROR_QUEUE_NAME", maxDeliveryAttempts: 3 );
} )
.Start();
}
Run Code Online (Sandbox Code Playgroud)
但是,当调试器进入第二个 Configure.With( ... ) 调用时,我以错误提示终止:
IBus 类型已经注册。如果您打算解析 IBus 实现的集合,请使用 RegisterCollection 重载。更多信息:https : //simpleinjector.org/coll1。如果您打算用此新注册替换现有注册,您可以通过将 Container.Options.AllowOverridingRegistrations 设置为 true 来允许覆盖当前注册。更多信息:https : //simpleinjector.org/ovrrd。
堆栈跟踪:
[InvalidOperationException: Type IBus has already been registered. If your intention is to resolve a collection of IBus implementations, use the RegisterCollection overloads. More info: https://simpleinjector.org/coll1. If your intention is to replace the existing registration with this new registration, you can allow overriding the current registration by setting Container.Options.AllowOverridingRegistrations to true. More info: https://simpleinjector.org/ovrrd.]
SimpleInjector.Internals.NonGenericRegistrationEntry.ThrowWhenTypeAlreadyRegistered(InstanceProducer producer) +102
SimpleInjector.Internals.NonGenericRegistrationEntry.Add(InstanceProducer producer) +59
SimpleInjector.Container.AddInstanceProducer(InstanceProducer producer) +105
SimpleInjector.Container.AddRegistrationInternal(Type serviceType, Registration registration) +69
SimpleInjector.Container.AddRegistration(Type serviceType, Registration registration) +131
SimpleInjector.Container.RegisterSingleton(TService instance) +183
Rebus.SimpleInjector.SimpleInjectorContainerAdapter.SetBus(IBus bus) +55
Rebus.Config.RebusConfigurer.Start() +2356
MyModule.RegisterServices(Container container) +497
SimpleInjector.PackageExtensions.RegisterPackages(Container container, IEnumerable`1 assemblies) +50
Myproject.SimpleInjectorInitializer.InitializeContainer(Container container) +35
Myproject.SimpleInjectorInitializer.Initialize() +68
Myproject.Startup.Configuration(IAppBuilder app) +28
Run Code Online (Sandbox Code Playgroud)
编辑
然后我删除了第二个Configure.With( ... )代码块,现在当我做一个时,我_bus.Send( message )在消费者进程中遇到另一个错误,它说
处理 ID 为 fef3acca-97f4-4495-b09d-96e6c9f66c4d 的消息时未处理的异常 1:SimpleInjector.ActivationException:找不到 IEnumerable<IHandleMessages<MyMessage>> 类型的注册。然而,有一个 IHandleMessages<MyMessage> 的注册;你是想调用 GetInstance<IHandleMessages<MyMessage>>() 还是依赖 IHandleMessages<MyMessage>?或者您的意思是使用 RegisterCollection 注册类型集合?
堆栈跟踪:
2017-04-13 10:21:03,805 [77] WARN Rebus.Retry.ErrorTracking.InMemErrorTracker -
at SimpleInjector.Container.ThrowMissingInstanceProducerException(Type serviceType)
at SimpleInjector.Container.GetInstanceForRootType[TService]()
at SimpleInjector.Container.GetInstance[TService]()
at SimpleInjector.Container.GetAllInstances[TService]()
at Rebus.SimpleInjector.SimpleInjectorContainerAdapter.<GetHandlers>d__3`1.MoveNext()
Run Code Online (Sandbox Code Playgroud)
我通常建议IBus每个容器实例只保留一个,因为总线本身可以被视为“一个应用程序”,这恰好符合 IoC 容器是一个可以在其持续时间内“托管”应用程序的对象的事实。寿命。
Rebus 没有提供 Conforming Container 抽象,因为我同意 Mark Seemann 的观点,这是一个注定要失败的项目。事实上,正如wiki 页面所提到的,Rebus 曾经提供处理程序的自动注册,但结果证明这是有问题的。
相反,Rebus 鼓励您提供一个“容器适配器”(实现IContainerAdapter),其职责是:
IBus并IMessageContext以正确的方式其中容器适配器是为 Autofac、Castle Windsor、SimpleInjector 等提供开箱即用的。但是,不需要提供容器适配器——Configure.With(...)咆哮很高兴只收到一个“处理程序激活器”(实现IHandlerActivator),所以如果你只想要使用您的 IoC 容器来查找处理程序并自行注册IBus,您也可以通过IHandlerActivator在容器中实现和查找处理程序来做到这一点。
TL;DR:Rebus 方式是将 IoC 容器的实例视为一个单独的应用程序,因此只IBus在其中注册一个是有意义的。
在单个进程中新建多个容器实例(或什至具有不同消息 SLA 的应用程序的多个实例)的多个容器实例是完全没问题的。
| 归档时间: |
|
| 查看次数: |
1229 次 |
| 最近记录: |