ProblemASP.NET MVC-Anwendung mit Plugin und Multitenancy-Unterstützung mit separaten AppDomains?
I eine ASP.NET MVC 3 Anwendung haben, mit der Steck/Modularchitektur und Multi-Tenant Unterstützung. MEF wird verwendet, um Abhängigkeiten aufzulösen und steckbare Teile zu laden.
Jedes Modul besteht aus Controllern, Ansichten und anderen Objekten (physikalisch ist es eine Baugruppe). Module werden in Mieter geladen.
Die einfache Konfiguration könnte wie folgt aussehen:
Tenant 1:
- Modul A, Version 1.0 (ModuleA.dll)
- Modul B, Version 1.0 (ModuleB.dll)
Mieter 2:
- Modul B, Version 1.0 (ModuleB.dll)
DLL für verschiedene Module und verschiedene Versionen werden separat in verschiedenen physischen Standorten gespeichert. Und Anwendung läuft auf einer AppDomain (standardmäßig eine).
Wenn wir jedoch eine Konfiguration durchführen möchten, bei der verschiedene Mandanten unterschiedliche Modulversionen verwenden, treten Probleme beim Laden derselben Baugruppe in verschiedenen Versionen auf. Das bedeutet, dass das folgende Szenario nicht voll funktionsfähig ist, da wir beim Auflösen von Typen aus ModuleB eine Ausnahme für die Kompositionsabweichung erhalten haben (Version 1.0 und 1.5 wurde in MEF geladen, aber nur eine Assembly wurde vom Assemblyloader in AppDomain geladen).
Tenant 1:
- Module A, Version 1.0 (ModuleA.dll)
- Modul B, Version 1.0 (ModuleB.dll)
Tenant 2:
- Modul A, Version 1.5 (ModuleB.dll)
Lösung?
Also kamen wir auf eine Lösung, die verschiedene Mieter und ihre Module/Baugruppen in separate AppDomains laden. Das heißt, dass aus unserem Beispiel Tenant1 und Tenant2 in AppDomain1 und AppDomain2 geladen werden. In ASP.NET MVC-Pipeline angeschlossen wir in den Controller Fabrik, um bis zu richtigen Anwendungsdomäne zu wählen, die wie folgt aussehen:
- Anfrage standardmäßig AppDomain gehandhabt wird (die, die Web-Anwendung gestartet)
- Controller-Fabrik
- nimmt Tenant_Id aus der Anforderung und löst die richtige Steuerung von richtigen AppDomain (wir haben Tenant_Id-> Selbstanmeldung> AppDomain Beziehung)
- Returns ControllerProxy (die eine Proxy-Klasse, die IRegler implementiert und erbt MarshalByRefObject der Lage sein, cont passieren Rolle zwischen den verschiedenen App Domians)
- nimmt Tenant_Id aus der Anforderung und löst die richtige Steuerung von richtigen AppDomain (wir haben Tenant_Id-> Selbstanmeldung> AppDomain Beziehung)
- Aktion Invoker
- Proper Aktion auf Controller-Proxy-Objekt aufgerufen wird, und jetzt nimmt die Ausführung im Grunde liegenden App domian
- Und hier stieß man in Problem weil der Aufrufer der Aktion nicht serialisierbaren RequestContext an eine andere Anwendungsdomäne übergeben kann (mit anderen Worten, controllerProxy.Execute (RequestContext context) gibt eine Ausnahme bezüglich der Serialisierung aus)
Frage (n):
- Wie Request (non serialisierbares Objekt) zwischen Anwendungsdomänen in einer schönen Weise zu übergeben?
- Ist es möglich, in einen anderen Schritt in der Pipeline einzubinden, um die Ausführung an die zugrunde liegende App-Domäne umzuleiten (vor der Controller-Fabrik?)
- Oder irgendwelche Ideen über eine andere Lösung für dieses Problem?
Die Sache ist, dass wir in der Lage sein müssen, verschiedene Versionen von Plugins in verschiedene Mandanten zu laden (immer noch in der gleichen Webanwendung) und das Plugin-System, das Sie beschrieben haben, solche Szenarien nicht behandelt. Oder? – untoldex
Es ist nicht möglich. Sie können nicht verschiedene Assembly-Versionen in derselben App-Domäne verwenden, und ASP.NET verwaltet die AppDomain. Sie werden es bereuen, wenn Sie versuchen, andere App-Domains zu verwenden. – jgauffin
Sie können tatsächlich verschiedene Assembly-Versionen in derselben App-Domäne verwenden - indem Sie Assemblys ohne Kontext laden - aus dem Byte-Array (Assembly.Load (byte [])). Ich versuche gerade, es funktioniert zu bekommen, aber Probleme mit MEF ... – untoldex