如何使用带有simpleinjector的rebus

时间:2015-10-27 09:31:21

标签: c# simple-injector rebus

在我的公司,我们使用SimpleInjector作为我们的Io​​C框架,现在正在使用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:\HRG\TravTech\Springboard\SearchType\SearchType.ProjectionA\Program.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:\HRG\TravTech\Springboard\SearchType\SearchType.ProjectionA\Program.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:\HRG\TravTech\Springboard\SearchType\SearchType.ProjectionA\Program.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只能在消息处理程序中实例化。有没有办法忽略某些错误?

1 个答案:

答案 0 :(得分:1)

我认为例外是明确的;简单的注入器在您已经解决后阻止注册。执行此操作的原因如here所述。

解决方案是手动创建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();