2017-08-25 5 views
1

シナリオ:複数の衛星ライブラリに REBUS変更を壊す

  • の.NET Framework 4.6
  • シンプルインジェクター
  • を使用して

    • のWeb APIアプリケーションREBUS
    • Rebus.AzureServiceBus
    • REBUS .SimpleInjector

    私のアプリケーションには、複数の衛星ライブラリがあり、そのほとんどがSimpleInjector IPackageインタフェースを実装するクラスを持っています。つまり、別のライブラリのコンテナ登録をグループ化するためです。

    • REBUS 4.0.1
    • :これらのパッケージは、パッケージの

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

      一つは、私たちは、次のバージョンにREBUSパッケージをアップグレードした今朝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.AzureServiceBus 4.0.0
    • Rebus

    システムをアップグレードした後.SimpleInjector 4.0.0は動作を停止し、今、私たちは次のようなエラーに

    コンテナがでGetInstanceへの最初の呼び出し後に変更することはできません、 GetAllInstancesを取得し、確認してください。コンテナが にロックされている理由を理解するには、 https://simpleinjector.org/lockedを参照してください。私たちは別のパッケージがREBUSとエラーのように理由を登録する1後に登録を受けることが確認できたコードにデバッグすることで

    次のスタックトレースが コンテナがロックされていた場所を示しています。コードで修正が行われておらず、以前のリリースでは正常に動作していたことが確認できました。

    私はまた、これらのバージョンに問題をダウングレードすることで消えることを確認することができます

    • REBUS 3.1.5
    • Rebus.AzureServiceBus 3.0.0
    • Rebus.SimpleInjector 3.0.0

    何か提案がありますか?

    EDIT:@Steven要求ごととして、私は完全なスタックトレース

    説明を追加してい:未処理の例外が 現在のWeb要求の実行中に発生しました。エラーについての詳細とコード内のどこで発生したのかについては、スタックトレースを参照してください。

    例外の詳細:System.InvalidOperationExceptionが:コンテナ はGetAllInstances でGetInstanceへの最初の呼び出し後に変更して確認してくださいすることはできません。 の理由を理解するには、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) 
    
  • +0

    確かに!私の編集を見てください。 – Lorenzo

    答えて

    3

    :)

    の下には、私は最終的にSimpleInjectorが行われるコンテナの登録を望んでいるかを理解し、どのようにREBUS設定APIを理解するための時間を持っていました何とかそのように動作するように曲がることができます。

    は、それはいつもの

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

    呪文は、それが可能実際にバスを開始する前に、すべてのREBUS関連の登録を終える(だけでなく、あなた自身の)すること、Func<IBus>に何とか移動しなければならなかったことが判明しました。

    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を使用している場合は見ることができる方法です。(ちょうど今NuGet.org上Rebus.SimpleInjector 5.0.0-B01に出ている)

    結果は、このAPIであります、または単に

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

    あなたが持っているものはすべてSimpleInjector containerです。

    あなたはバスを起動するための時間だと思うときIBusが解決されるまで、あなたのいずれか

    container.StartBus(); 
    

    またはあなたが待ちます。

    +1

    こんにちは@ mookid8000、あなたの説明に感謝します。毎晩大盛況が続いているようです。私はこの新しい実装についてより多くのテストを行い、それについていくつかの知見を得るかどうかを知らせます。どうもありがとう! – Lorenzo

    +0

    よろしくお願いします! :) – mookid8000

    +1

    偉大な仕事!閉鎖。もう一度ありがとう! – Lorenzo

    0

    をごEndpointEventsProducerModuleRebusConfigurer.Startを呼んでいます。開始はコンテナからIBusを解決します。

    モジュールは任意の順序で呼び出すことができるため、モジュールで登録する必要があります。 Startの呼び出しを削除し、container.Verify()の呼び出しの後に呼び出します。

    +0

    イルあなたの答えスティーブンありがとう。そのモジュールの内容は、私が書いた質問の冒頭にあります。これは以前のバージョンのパッケージと同じコードです。 – Lorenzo

    +0

    私はそれについて知らない。あなたはそれについてRebusの開発者に尋ねなければなりません。 – Steven

    2

    hereが表示されているように、バスが廃棄されていることを確認するために追加された新しいコードが追加されました。問題が発生しました。コードはうまくいくようです。この質問に反応するように後半にあることのため申し訳ありませんが、新しいライン

    +   // cheat and activate the IBus singleton behind the scenes, thus ensuring that the container will dispose it when it is time 
    +   var registration = _container.GetRegistration(typeof(IBus)); 
    + +   registration.GetInstance(); 
    + 
    
    関連する問題