2012-04-26 10 views
5

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)
  • 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?

Antwort

1

Nicht möglich. ASP.NET wird zurückkommen und Sie verfolgen, wenn Sie versuchen, verschiedene AppDomains zu verwenden.

Verwenden Sie stattdessen die rollenbasierte Autorisierung, um den Zugriff für die verschiedenen Module zu steuern.

Ich habe gerade einen Artikel über Plug-Systeme in ASP.NET MVC3 geschrieben: http://blog.gauffin.org/2012/05/griffin-mvccontrib-the-plugin-system/

+0

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

+0

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

+0

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

0

Dies gilt nicht direkt Ihre Frage über mehrere Anwendungsdomänen innerhalb ASP.NET MVC beantworten. In Bezug auf andere Optionen können Sie jedoch das Managed Application Framework (a.k.a.System.Addin) ausprobieren. Es ist Teil von .NET Framework und ähnelt MEF insofern, als es das dynamische Laden von Modulen unterstützt. Es verfügt jedoch über integrierte Funktionen zum Teilen dieser Module über App-Domänen hinweg. Es könnte besser für Ihre Bedürfnisse geeignet sein. Ich bin mir nicht sicher, wie gut es mit ASP.NET MVC passt.

Diese document on MSDN sollten Sie mit MAF beginnen.