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

您不能使用 XElement 跨 AppDomain 边界。潜在原因 - XElement 可以表示必须跨 AppDomain 边界编组的巨大对象树/大量数据。

虽然您可以让您的代码工作(即通过保存到流和重新加载),但这可能不是最好的主意。您将丢失元素(即父级)的上下文,并且您可能会无意中序列化/反序列化大量数据。考虑以这样一种方式进行重构,即在创建 XElement 的新 AppDomain 中处理 XElement 的数据,然后将自定义对象(可序列化或通过 ref 编组)返回到主 AppDomain。

笔记:

  • 我假设您的示例代码只是示例,创建/拆除 AppDomain 以调用单个方法并不是地球上最快的事情。如果它是一次性操作可能完全没问题,但如果它以任何非平凡的频率重复,请确保检查性能是否符合您的目标。
  • 你不需要catch/throw如果你只需要finally(再次假设实际代码超过throw
于 2012-09-20T16:17:04.823 回答
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 回答