2017-08-25 28 views
1

方案:使用多個衛星庫 滷麪用簡單的注射器重大更改

  • 的.NET Framework 4.6
  • 簡單的注射器
  • 滷麪
  • Rebus.AzureServiceBus
  • 滷麪

    • 的Web API應用程序。簡單的噴油器

    在我的應用程序中有多個衛星庫,其中大多數都有一個實現SimpleInjector接口的類,即將容器註冊分組到不同庫中。這些軟件包獲得註冊在啓動時

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

    一個軟件包包含滷麪配置

    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(); 
    

    今天上午,我們已經升級滷麪包以下版本:

    • 滷麪4.0.1
    • Rebus.AzureServiceBus 4.0.0
    • Rebus .SimpleInjector 4.0.0

    的升級系統後停止工作,現在我們得到以下錯誤

    的容器不能在第一次調用的GetInstance後改變, GetAllInstances和驗證。請參閱 https://simpleinjector.org/locked瞭解爲什麼容器被鎖定爲 。下面的堆棧跟蹤,說明了 容器鎖定的位置:

    通過上我們可以看到,另一包拿到註冊畫謎和錯誤的這樣的原因一前一後註冊的代碼調試。我們可以確認沒有對代碼進行任何修改,並且在以前的版本中按預期正確工作。

    我還可以確認通過降級到這些版本的問題消失

    • 滷麪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) 
    
  • +0

    當然!請看看我的編輯。 – Lorenzo

    回答

    3

    對不起,我是來晚了這個問題:)

    我終於有時間去了解如何SimpleInjector要進行註冊的容器,並瞭解滷麪配置API反應可以以某種方式彎曲成這樣工作。

    原來,平時

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

    法術必須在某種意義上被移入Func<IBus>,使其能夠在實際開始總線之前完成所有滷麪相關注冊(以及你自己)。

    結果(這是出在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得到解決。

    +1

    你好@ mookid8000,謝謝你的解釋。似乎所有人都在努力工作。我會對這個新的實現做更多的測試,並且讓我們知道我是否會收到關於它的一些發現。非常感謝! – Lorenzo

    +0

    很好聽! :) – mookid8000

    +1

    偉大的工作!關閉。再次感謝! – Lorenzo

    0

    EndpointEventsProducerModule呼籲RebusConfigurer.Start。開始從容器中解析IBus

    由於模塊可以按任何順序調用,因此您只應在模塊中進行註冊。調用Start調用並在您調用container.Verify()後調用它。

    +0

    Il謝謝你的回答史蒂文。該模塊的內容恰好在我寫的問題的開頭。這是與以前版本的軟件包一樣的代碼。 – 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(); 
    + 
    
    相關問題