场景:


使用多个卫星库的Web API应用程序
.NET Framework 4.6
简单喷油器
汇流
Rebus.AzureServiceBus
Rebus.SimpleInjector


在我的应用程序中,有多个附属库,其中大多数都有一个实现SimpleInjector IPackage接口的类,即将容器注册分组到不同的库中。这些软件包在启动时注册

container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies());


软件包之一包含Rebus配置

IContainerAdapter adapter = new SimpleInjectorContainerAdapter( container );
Configure.With( adapter )
            .Transport( t => t.UseAzureServiceBusAsOneWayClient( connectionString, AzureServiceBusMode.Standard ) )
            .Routing( r =>
            r.TypeBased()
                .MapAssemblyOf<TransactionCreated>( "MyQueue" )
            )
            .Options( oc => {
                oc.SetNumberOfWorkers( 1 );
            } )
            .Start();


今天早上,我们已将Rebus软件包升级到以下版本:


汇聚4.0.1
Rebus.AzureServiceBus 4.0.0
Rebus.SimpleInjector 4.0.0


升级后,系统停止工作,现在出现以下错误


  首次调用GetInstance后无法更改容器,
  GetAllInstances和验证。请参见
  https://simpleinjector.org/locked了解为什么容器是
  锁定。以下堆栈跟踪说明了
  容器被锁定:


通过对代码进行调试,我们可以看到在注册了rebus的另一个软件包之后又注册了另一个软件包,因此是错误的原因。我们可以确认未对代码进行任何修改,并且可以按照以前的版本正常工作。

我还可以确认通过降级到这些版本,问题消失了


中继3.1.5
Rebus.AzureServiceBus 3.0.0
Rebus.SimpleInjector 3.0.0


有什么建议吗?

编辑:根据@Steven请求,我正在添加完整的堆栈跟踪


  说明:在执行期间发生未处理的异常
  当前的Web请求。请查看堆栈跟踪以获取更多信息
  有关错误及其在代码中起源的信息。
  
  异常详细信息:System.InvalidOperationException:容器
  在第一次调用GetInstance,GetAllInstances之后不能更改
  和验证。请参阅https://simpleinjector.org/locked了解
  为什么容器被锁定。以下堆栈跟踪描述了
  容器被锁定的位置:


at Rebus.SimpleInjector.SimpleInjectorContainerAdapter.SetBus(IBus bus)
at Rebus.Config.RebusConfigurer.Start()
at XXX.YYY.EndpointEvents.Producer.IOC.EndpointEventsProducerModule.RegisterServices(Container container)
at SimpleInjector.PackageExtensions.RegisterPackages(Container container, IEnumerable assemblies)
at XXX.YYY.WebAPI.SimpleInjectorWebApiInitializer.InitializeContainer(Container container)
at XXX.YYY.WebAPI.SimpleInjectorWebApiInitializer.Initialize()
at XXX.YYY.WebAPI.Startup.Configuration(IAppBuilder app)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Owin.Loader.DefaultLoader.<>c__DisplayClass12.<MakeDelegate>b__b(IAppBuilder builder)
at Owin.Loader.DefaultLoader.<>c__DisplayClass1<LoadImplementation>b__0(IAppBuilder builder)
at Microsoft.Owin.Host.SystemWeb.OwinHttpModule.<>c__DisplayClass2.<InitializeBlueprint>b__0(IAppBuilder builder)
at Microsoft.Owin.Host.SystemWeb.OwinAppContext.Initialize(Action startup)
at Microsoft.Owin.Host.SystemWeb.OwinBuilder.Build(Action startup)
at Microsoft.Owin.Host.SystemWeb.OwinHttpModule.InitializeBlueprint()
at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Boolean& initialized, Object& syncLock, Func valueFactory)
at Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(HttpApplication context)
at System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
at System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
at System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
at System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)

最佳答案

对不起对这个问题做出反应了:)

我终于有时间了解SimpleInjector如何进行容器注册,并了解Rebus配置API如何以某种方式致力于这种工作。

原来,通常

Configure.With(new MyFavoriteContainerAdapter(container))
    .(...)
    .Start();


必须将咒语以某种方式移到Func<IBus>中,从而有可能在实际启动总线之前完成所有与Rebus相关的注册(以及您自己的注册)。

结果(现在在NuGet.org的Rebus.SimpleInjector 5.0.0-b01中显示)是以下API:

public class RebusPackage : IPackage
{
    public void RegisterServices(Container container)
    {
        Console.WriteLine("Calling RebusPackage");

        container.ConfigureRebus(
            configurer => configurer
                .Transport(t => t.UseInMemoryTransport(new InMemNetwork(), "test"))
                .Start()
        );

    }
}


如果您使用的是SimpleInjector.Packaging,或者只是使用它,它的外观将如何

container.ConfigureRebus(
    configurer => configurer
        .Transport(t => t.UseInMemoryTransport(new InMemNetwork(), "test"))
        .Start()
);


如果您只有一个SimpleInjector container

当您认为是时候启动巴士了,您要么

container.StartBus();


或等到IBus解决。

关于c# - 通过简单的喷油器突破性变化进行重燃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45886811/

10-11 11:46