2013-10-07 5 views
5

私のWPFアプリケーションでプラグインを使用できるようにしようとしています。 。しかし、追加のアプリケーションドメインを作成するために)提案しています。このためプラグインで使用するアプリケーションドメインを作成する:「アセンブリの型がシリアル化可能とマークされていません

、私は私の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); 
    } 

しかし、UnhandledExceptionイベントが例外で失敗取り付け:

'MyProject、Version = 1.0.0.0、Culture = neutral、PublicKeyToken = 1337'アセンブリの 'MyProject.App'タイプはシリアル化可能としてマークされていません。

何が問題になりますか?

答えて

9

.NET Remotingは、子AppDomainからPluginAppDomain_UnhandledExceptionにアクセスする必要があります。 PluginAppDomain_UnhandledExceptionはインスタンスメソッドであるため、このクラスの子オブジェクトAppDomainは現在のオブジェクト(this)を使用してアクセスする必要があります。これを行うには2つの方法があります。 1つは、クラスをMarshalByRefObjectから派生させることです。このクラスは、プロキシ経由で他のAppDomainsからインスタンスにアクセスできるようにします。もう1つの方法は、クラスをSerializableAttributeでデコレートし、.NET Remotingがこのクラスのインスタンスを他のAppDomainsにシリアル化できることを認識させる方法です。このため、シリアライズ可能なエラーが発生します。あなたのクラスは1)MarshalByRefObjectから派生し、2)はSerializableとマークされていません。

私の知る限り、このイベントを別のAppDomainから購読することはお勧めできません。このクラスを作成して、LoggerのクラスをMarshalByRefObjectから派生させても、AppDomains間で例外を渡すため、優れた解決方法からは遠いでしょう。このためにはが必要です。のすべての例外は、AppDomains間でのシリアル化可能なになり、そのアセンブリは両方のAppDomainsにロードされます。これは、プラグインを分離したい場合には問題になる可能性があります。

私があなただったら、最初に別のAppDomainsを扱わずにアプリケーションをプラグインに対応させることになりました。 AppDomainsとUnhandleExceptionsの協調作業はすべて非常に複雑です。

次に、MarshalByRefObjectの派生オブジェクトを使用してみます(PluginAppDomain_UnhandledExceptionが静的にされている場合はLoggerで十分です)、Loggerのメソッドに文字列を渡します。

それ以外の場合は、プラグインに別のログを渡すか、Windowsイベントログを使用します。

関連する問題