2013-10-07 4 views
5

Ich versuche, Plug-ins in meiner WPF-Anwendung zu aktivieren. Soweit mir bekannt ist, brauche ich (na ja, nicht nötig ., aber es wird empfohlen) eine zusätzliche Anwendungsdomäne erstellenApp-Domäne für die Verwendung mit Plugins erstellen: "Assembly eingeben ist nicht als serialisierbar markiert

Dafür ich in meinem App.xaml.cs folgende beim Start so mache:

private void LoadPlugins() 
    { 
     // Create and polish plugin app domain 
     AppDomain pluginAppDomain = AppDomain.CreateDomain("MyProject Plugin Container", null); 
     pluginAppDomain.UnhandledException += PluginAppDomain_UnhandledException; 

     //TODO: Load plugins from dlls 
    } 

    private void PluginAppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Logger.FatalException("PluginAppDomain", e.ExceptionObject as Exception); 
    } 

aber das UnhandledException Ereignis Befestigung schlägt mit Ausnahme :

Typ 'MyProject.App' in Assembly 'MyProject, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 1337' ist nicht als serialisierbar gekennzeichnet.

Was könnte das Problem sein?

Antwort

9

.NET Remoting muss auf PluginAppDomain_UnhandledException von der untergeordneten AppDomain zugreifen. PluginAppDomain_UnhandledException ist eine Instanzmethode und daher muss die untergeordnete Anwendungsdomäne über das aktuelle Objekt (dieses) aus dieser Klasse darauf zugreifen. Es gibt zwei Möglichkeiten, dies zu tun. Eine besteht darin, die Klasse von MarshalByRefObject abzuleiten, was den Zugriff auf Instanzen von anderen AppDomains über Proxies ermöglicht. Die andere Möglichkeit, die Klasse mit der SerializableAttribute zu dekorieren und .NET Remoting wissen zu lassen, dass diese Instanz dieser Klasse in andere AppDomains serialisiert werden kann. Das ist der Grund, warum Sie den serialisierbaren Fehler erhalten. Ihre Klasse wird nicht 1) abgeleitet von MarshalByRefObject und 2) wird nicht als Serializable markiert.

Soweit ich weiß, ist es keine sehr gute Idee, diese Veranstaltung von einem anderen AppDomain zu abonnieren. Sie sehen, selbst wenn Sie diese Klasse und die Klasse Logger von MarshalByRefObject abgeleitet werden, werden Sie immer noch ein langer Weg von einer guten Lösung sein, weil Sie Ausnahmen zwischen AppDomains übergeben. Damit dies funktioniert, benötigen Sie alle Ausnahmen zwischen den AppDomains serialisierbar und ihre Assemblys in beiden AppDomains geladen werden. Dies kann ein Problem sein, wenn Sie Plugins isolieren möchten.

Wenn ich Sie wäre, würde ich zuerst meine Anwendung plugin-aware, ohne sich mit separaten AppDomains befassen. Die ganze Sache mit AppDomains und UnhandleExceptions ist ziemlich kompliziert.

Dann könnte ich Ihren Ansatz versuchen, aber mit MarshalByRefObject abgeleiteten Objekten (nur der Logger genügt, wenn die PluginAppDomain_UnhandledException statisch gemacht wird) und nur Strings die Logger ‚s Methoden übergeben.

Ansonsten würde ich nur ein separates Protokoll zum Plugin geben oder das Windows Event Log verwenden.