2013-10-07 15 views
5

Sto tentando di abilitare la possibilità di utilizzare plugin nella mia applicazione WPF. Per quanto ne so, ho bisogno (beh, non serve ., ma è suggerito) per creare un dominio applicazione aggiuntivaCrea dominio app da utilizzare con i plugin: "Digitare assembly non è contrassegnato come serializzabile

per questo, sto facendo il seguente all'avvio nei miei App.xaml.cs:

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

ma allegando l'evento UnhandledException non riesce ad eccezione :

Digitare "MyProject.App" nell'assembly "MyProject, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 1337" non è contrassegnato come serializzabile.

Quale potrebbe essere il problema?

risposta

9

.NET Remoting deve accedere a PluginAppDomain_UnhandledException dal figlio AppDomain. PluginAppDomain_UnhandledException è un metodo di istanza e pertanto il figlio AppDomain deve accedervi tramite l'oggetto corrente (questo) da questa classe. Ci sono due modi per farlo. Uno consiste nel far derivare la classe da MarshalByRefObject che consentirà l'accesso alle istanze da altri AppDomain tramite proxy. In alternativa, per decorare la classe con SerializableAttribute e consentire a .NET Remoting di sapere che l'istanza di questa classe può essere serializzata su altri AppDomain. Questo è il motivo per cui ottieni l'errore serializzabile. La tua classe non 1) deriva da MarshalByRefObject e 2) non è contrassegnata come Serializable.

Per quanto ne so, non è una buona idea iscriversi a questo evento da un altro AppDomain. Si vede anche se si crea questa classe e la classe di Logger derivata da MarshalByRefObject sarà ancora molto lontana da una buona soluzione perché si passano eccezioni tra AppDomain. Quindi, affinché funzioni, è necessario il numero di tutte le eccezioni passate tra gli AppDomain per essere serializzabile e gli assembly caricati in entrambi gli AppDomain. Questo potrebbe essere un problema se vuoi isolare i plugin.

Se fossi in te, vorrei innanzitutto rendere la mia applicazione in grado di riconoscere i plug-in senza occuparsi di AppDomain separati. L'intera faccenda di AppDomains e UnhandleExceptions è piuttosto complicata.

Quindi potrei provare il tuo approccio ma con gli oggetti derivati ​​MarshalByRefObject (solo il Logger è sufficiente se PluginAppDomain_UnhandledException è reso statico) e passare solo le stringhe ai metodi di Logger.

In caso contrario, fornirei semplicemente un registro separato al plug-in o utilizzare il registro eventi di Windows.

Problemi correlati