2017-08-25 3 views
1

Szenario:Rebus mit einfachen Injector brechen Änderung

  • Web-API-Anwendung mehr Satelliten-Bibliothek
  • .NET Framework 4.6
  • Einfachen Injector
  • Rebus
  • Rebus.AzureServiceBus mit
  • Rebus .SimpleInjector

In meiner Anwendung gibt es mehrere Satelliten-Bibliothek, von denen die meisten eine Klasse implementieren SimpleInjector IPackage Schnittstelle, dh Container-Registrierungen in verschiedenen Bibliotheken zu gruppieren. Diese Pakete erhalten beim Start registriert

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

Eines der Pakete enthält Rebus Konfiguration

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

Heute Morgen haben wir Rebus-Pakete für die folgenden Versionen aktualisiert haben:

  • Rebus 4.0.1
  • Rebus.AzureServiceBus 4.0.0
  • Rebus 4.0.0 .SimpleInjector

Nach dem Upgrade des Systems aufgehört zu arbeiten und jetzt bekommen wir die folgenden Fehler

Der Behälter kann nicht nach dem ersten Aufruf zu GetInstance, GetAllInstances und Überprüfen geändert werden. Bitte beachten Sie https://simpleinjector.org/locked zu verstehen, warum der Container gesperrt ist. Die folgende Stack-Trace beschreibt den Ort, wo der Behälter verschlossen war:

auf dem Code von Debuggen wir, dass ein anderes Paket nach dem einen, die Rebus registrieren registrieren lassen sehen können und so den Grund des Fehlers. Wir können bestätigen, dass am Code keine Änderungen vorgenommen wurden und dass er ordnungsgemäß wie erwartet mit den vorherigen Releases funktioniert hat.

Ich kann auch bestätigen, dass auf diese Versionen das Problem durch die Herabstufung

  • Rebus 3.1.5
  • Rebus.AzureServiceBus 3.0.0
  • Rebus.SimpleInjector 3.0.0
verschwinden

Irgendwelche Vorschläge?

EDIT: Wie pro @ Steven Anfrage Ich füge den vollständigen Stack-Trace

Beschreibung: Eine nicht behandelte Ausnahme trat während der Ausführung von der aktuellen Web-Anfrage.Bitte überprüfen Sie die Stack-Trace für weitere Informationen über den Fehler und wo es im Code entstanden ist.

Ausnahmedetails: System.InvalidOperationException: Der Behälter kann nicht nach dem ersten Aufruf zu GetInstance, GetAllInstances und Überprüfen geändert werden. Bitte beachten Sie https://simpleinjector.org/locked zu verstehen, warum der Behälter verschlossen ist. Die folgende Stack-Trace beschreibt die Ort, an dem der Behälter verschlossen war:

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

Sure! Bitte sehen Sie sich meine Bearbeitung an. – Lorenzo

Antwort

3

Sorry für zu spät auf diese Frage zu reagieren :)

ich die Zeit, schließlich hatte zu verstehen, wie SimpleInjector will Anmeldungen Container gemacht werden, und zu verstehen, wie die Rebus Konfigurations-API könnte irgendwie dazu gebracht werden, so zu arbeiten.

Es stellte sich heraus, dass die übliche

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

Zauber irgendwie in eine Func<IBus> verschoben werden musste, was es ermöglicht, alle Rebus relevanten Registrierungen (wie auch Ihre eigene) zu beenden, bevor der Bus tatsächlich beginnen.

Das Ergebnis (die aus ist in Rebus.SimpleInjector 5.0.0-b01 auf NuGet.org jetzt gerade) ist diese 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() 
     ); 

    } 
} 

, die ist, wie es aussehen kann, wenn man SimpleInjector.Packaging verwenden oder einfach

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

, wenn alles, was Sie haben, ist ein SimpleInjector container.

Wenn Sie denken, dass es Zeit ist, den Bus zu starten, können Sie entweder

container.StartBus(); 

oder Sie warten, bis IBus behoben ist.

+1

Hallo @ Mookid8000, danke für deine Erklärung. Es scheint, dass Everyhting wieder großartig funktioniert. Ich werde mehr Tests zu dieser neuen Implementierung machen und Sie wissen lassen, ob ich einige Erkenntnisse darüber gewinnen werde. Danke vielmals! – Lorenzo

+0

gut zu hören! :) – mookid8000

+1

Gute Arbeit! Schließen. Noch einmal Danke! – Lorenzo

0

Ihre EndpointEventsProducerModule ruft RebusConfigurer.Start. Start löst IBus aus dem Container.

Da Module können in beliebiger Reihenfolge aufgerufen werden, sollten Sie nur Eintragungen in Module machen. Entfernen Sie den Start Aufruf und rufen Sie es nach Ihrem Aufruf von container.Verify() auf.

+0

Il Danke für deine Antwort Steven. Der Inhalt dieses Moduls steht genau am Anfang der Frage, die ich geschrieben habe. Das ist der gleiche Code, der mit früheren Versionen der Pakete funktioniert. – Lorenzo

+0

Ich weiß nicht darüber. Sie müssen die Rebus-Entwickler danach fragen. – Steven

2

Wie Sie sehen können here gibt es neue codierte hinzugefügt, um sicherzustellen, dass der Bus entsorgt wird, dass ein Problem eingeführt, scheint Ihr Code in Ordnung zu sein, müssen nur die Reparatur warten. Unter den neuen Linien

+   // 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(); 
+ 
Verwandte Themen