1

さまざまな dll ファイルから外部アセンブリをロードするアプリケーションがあります。以前に作成した別のドメインにアセンブリをロードしています。すべてのアセンブリは XElement オブジェクトを返します。このオブジェクトをメイン AppDomain の別のメソッドに使用する必要がありますが、XElement オブジェクトには Serializable 属性がないため、このオブジェクトをそのまま送信できません。外部ライブラリから XElement オブジェクトを取得することは非常に重要です。これにシリアル化を使用しようとしましたが、毎回失敗します。

ラップクラスを作成してみました。このクラスは XElement からストリームを作成するだけで、メイン ドメインでこのストリームから読み込もうとしていますが、このストリームはその時点で閉じられています。

誰かがこの問題を解決するのを手伝ってくれたら、とてもうれしいです。ありがとうございます。

private XElement CallModule(string modulePath, string moduleName, 
  Dictionary<string, string> parameters)
{
  AppDomainSetup moduleDomainSetup = new AppDomainSetup();
  moduleDomainSetup.ApplicationBase = AppDomain.CurrentDomain.RelativeSearchPath;
  AppDomain moduleDomain = 
    AppDomain.CreateDomain("moduleDomain", null, moduleDomainSetup);

  try
  {
     Module remoteobj =  (Module)moduleDomain.CreateInstanceFromAndUnwrap(
       HttpContext.Current.Request.MapPath(modulePath),
       moduleName + "." + moduleName);
     Module.WrappedStream remoteResult = 
       remoteobj.Execute(queryString["command"], parameters);

     XElement res = XElement.Load(remoteResult.Stream);
     return res;
  }
  catch (Exception ex)
  {
    throw ex;
  }
  finally
  {
    AppDomain.Unload(moduleDomain);
  }
}
4

3 に答える 3

1

XElement.Saveを使用して、TextWriter または Stream に保存できます。

于 2012-09-20T16:01:38.453 に答える
0
Module remoteobj =  (Module)moduleDomain.CreateInstanceFromAndUnwrap(
       HttpContext.Current.Request.MapPath(modulePath),
       moduleName + "." + moduleName);
     Module.WrappedStream remoteResult = 
       remoteobj.Execute(queryString["command"], parameters);

     XElement res = XElement.Load(remoteResult.Stream);
     return res;

XElement をシリアル化するのではなく、modulePath、moduleName、およびパラメーターをシリアル化し、後で modulePath、moduleName、およびパラメーターを使用して XElement オブジェクトを再作成することは可能ですか。

コマンドパターンでこれを試すこともできますか?

于 2012-09-20T16:28:17.873 に答える
0

AppDomain の境界を越えて XElement を使用することはできません。考えられる理由 - XElement は、AppDomain 境界を越えてマーシャリングする必要がある巨大なオブジェクト ツリー/大量のデータを表すことができます。

コードを動作させることはできますが (つまり、ストリームに保存してリロードすることによって)、それは最良のアイデアではないかもしれません。要素 (つまり、親) のコンテキストが失われ、大量のデータを誤ってシリアル化/逆シリアル化する可​​能性があります。XElement のデータが作成された新しい AppDomain 内で処理し、カスタム オブジェクト (serialzable または ref によるマーシャリング) をメインの AppDomain に返すようにリファクタリングすることを検討してください。

ノート:

  • あなたのサンプルコードは単なるサンプルであり、単一のメソッドを呼び出すために AppDomain を作成/破棄することは、地球上で最速のものではないと思います。1 回限りの操作であればまったく問題ないかもしれませんが、重要な頻度で繰り返す場合は、パフォーマンスが目標を満たしているかどうかを確認してください。
  • あなたは必要ありませんcatch/throw必要なだけですfinally(ここでも、実際のコードが を超えると仮定しますthrow
于 2012-09-20T16:17:04.823 に答える