在我的公司,我们使用SimpleInjector作为我们的IoC框架,现在正在考虑使用Rebus作为通过RabbitMq发送消息的包装器。我正在寻找在创建一个工作的例子的帮助。我尝试了以下代码:
using Rebus.Activation;
using Rebus.Config;
using Rebus.Handlers;
using Rebus.Pipeline;
using Rebus.RabbitMq;
using Rebus.SimpleInjector;
using SimpleInjector;
using System;
using System.Threading.Tasks;
namespace SearchType.ProjectionA
{
class Program
{
static void Main(string[] args)
{
var container = new Container();
container.Register<IContainerAdapter, SimpleInjectorContainerAdapter>();
container.Register<IHandleMessages<string>, Handler>();
var adapter = container.GetInstance<IContainerAdapter>();
var bus = Configure.With(adapter)
.Logging(l => l.ColoredConsole())
.Transport(t => t.UseRabbitMq("amqp://localhost", "simpleinjector_consumer"))
.Start();
bus.Subscribe<string>().Wait();
Console.WriteLine("Projection A listening - press ENTER to quit");
Console.ReadLine();
}
}
public class Handler : IHandleMessages<string>
{
public Task Handle(string message)
{
return Task.Run(() =>
{
Console.WriteLine(string.Format("{0} - {1}", MessageContext.Current.Message.Headers["rbs2-corr-id"], message));
});
}
}
}
当我尝试运行这个控制台应用程序时,我得到以下错误:
System.InvalidOperationException was unhandled
HResult=-2146233079
Message=The container can't be changed after the first call to GetInstance, GetAllInstances and Verify. The following stack trace describes the location where the container was locked:
at SearchType.ProjectionA.Program.Main(String[] args) in C:HRGTravTechSpringboardSearchTypeSearchType.ProjectionAProgram.cs:line 34
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Source=SimpleInjector
StackTrace:
at SimpleInjector.Container.ThrowWhenContainerIsLocked()
at SimpleInjector.Container.AddRegistration(Type serviceType, Registration registration)
at SimpleInjector.Container.RegisterSingleton[TService](TService instance)
at Rebus.SimpleInjector.SimpleInjectorContainerAdapter.SetBus(IBus bus)
at Rebus.Config.RebusConfigurer.Start()
at SearchType.ProjectionA.Program.Main(String[] args) in C:HRGTravTechSpringboardSearchTypeSearchType.ProjectionAProgram.cs:line 36
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
有人知道我能做什么来解决这个问题吗?我不想自己声明所有的依赖项。
编辑:谢谢Steven的回复。我已经根据你的答案更改了代码,现在得到一个不同的错误。
System.InvalidOperationException was unhandled
HResult=-2146233079
Message=The configuration is invalid. Creating the instance for type IMessageContext failed. The registered delegate for type IMessageContext threw an exception. Attempted to inject the current message context from MessageContext.Current, but it was null! Did you attempt to resolve IMessageContext from outside of a Rebus message handler?
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
at SimpleInjector.Container.VerifyInstanceCreation(InstanceProducer[] producersToVerify)
at SimpleInjector.Container.VerifyThatAllRootObjectsCanBeCreated()
at SimpleInjector.Container.VerifyInternal(Boolean suppressLifestyleMismatchVerification)
at SimpleInjector.Container.Verify()
at SearchType.ProjectionA.Program.Main(String[] args) in C:HRGTravTechSpringboardSearchTypeSearchType.ProjectionAProgram.cs:line 27
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
HResult=-2146233088
Message=The registered delegate for type IMessageContext threw an exception. Attempted to inject the current message context from MessageContext.Current, but it was null! Did you attempt to resolve IMessageContext from outside of a Rebus message handler?
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
InnerException:
HResult=-2146233079
Message=Attempted to inject the current message context from MessageContext.Current, but it was null! Did you attempt to resolve IMessageContext from outside of a Rebus message handler?
Source=Rebus.SimpleInjector
StackTrace:
at Rebus.SimpleInjector.SimpleInjectorContainerAdapter.<SetBus>b__7()
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.BuildAndReplaceInstanceCreatorAndCreateFirstInstance()
at SimpleInjector.InstanceProducer.GetInstance()
InnerException:
该错误指示IMessageContext只能在消息处理程序中实例化。有没有一种方法可以忽略某些错误?
我认为例外是明确的;简单注入器防止注册后,你已经解决。此处描述了这样做的原因。
解决方案是手动创建SimpleInjectorContainerAdapter
,并防止依赖于容器的适配器自动连接功能:
var container = new Container();
IContainerAdapter adapter = new SimpleInjectorContainerAdapter(container);
container.Register<IHandleMessages<string>, Handler>();
var bus = Configure.With(adapter)
.Logging(l => l.ColoredConsole())
.Transport(t => t.UseRabbitMq("amqp://localhost", "simpleinjector_consumer"))
.Start();
container.Verify();