0

在我的应用程序中,我正在创建沙盒域,我需要动态定义绑定重定向规则。但是,我既不能使用 SetConfigurationBytes 方法传递 ConfigurationFile 设置也不能传递原始 xml 数据。

我创建了一个示例来检查配置数据是否应用于子域:

var configData =
@"<?xml version='1.0' encoding='utf-8' ?>
<configuration>
  <appSettings>
    <add key='MyData' value='CUSTOM'/>
  </appSettings>
</configuration>";
var setup = new AppDomainSetup {
ApplicationBase = runtimeAssembliesPath // ,ConfigurationFile = configFilePath
                };
setup.SetConfigurationBytes(Encoding.UTF8.GetBytes(configData));
var sandbox = AppDomain.CreateDomain("Sandbox", evidence, setup);
var verifier = (Sample)_sandbox.CreateInstanceAndUnwrap(thisAssemblyName, typeof(Sample).FullName);
verifier.DebugPrint();

其中 Verifier 是具有一种方法的普通类:

public class Sample: MarshalByRefObject 
{
    public void DebugPrint()
    {
        Debug.WriteLine("=====================================");
        Debug.Print("Reading config: =====|{0}|=====", ConfigurationManager.AppSettings["MyData"]);
        Debug.WriteLine("=====================================");
    }
}

更新 上面代码的第一个问题是,它必须从 MarshalByRefObject 继承,才能将 DebugPrint 调用编组到子 appdomain,而不是调用在当前域中创建的副本(感谢 sthotakura)。结果 ConfigurationFile 设置开始起作用。但是 SetConfigurationBytes 仍然没有运气。无论如何,目标是定义通过 SetConfigurationBytes 传递的绑定规则。

4

2 回答 2

2

要跨AppDomain边界访问对象,该类必须派生自MarshalByRefObject.

MSDN页面:

当跨应用程序域边界使用类型时,类型必须从 MarshalByRefObject 继承,并且不能复制对象的状态,因为对象的成员在创建它们的应用程序域之外不可用。

这意味着,您的示例类应该派生自MarshalByRefObject

[Serializable]
public class Sample : MarshalByRefObject
{
    public void DebugPrint()
    {
        Console.WriteLine("=====================================");
        Console.WriteLine(ConfigurationManager.AppSettings.Count);
        Console.WriteLine("Reading config: =====|{0}|=====", ConfigurationManager.AppSettings["MyData"]);
        Console.WriteLine("=====================================");
    }
}

我在一个示例应用程序中尝试过,但是使用 Config XML 而不是调用SetConfigurationData它并且它可以工作,下面是我的示例代码供您参考:

var setup = new AppDomainSetup();
setup.ConfigurationFile = "SandBoxConfig.xml";
var sandbox = AppDomain.CreateDomain("Sandbox", null, setup);
var verifier = (Sample)sandbox.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Sample).FullName);
verifier.DebugPrint();

编辑

来自 MSDN 页面,AppDomainSetup.SetConfigurationBytes 方法

配置文件信息的某些使用者不使用 SetConfigurationBytes 方法存储的信息。运行时不会强制执行此操作。要确保在新的应用程序域中替换所有配置文件信息,请使用 ConfigurationFile 属性来指定配置文件。SetConfigurationBytes 方法确实会影响程序集绑定。

因此,我怀疑System.Configuration命名空间中的类型(如ConfigurationManager)忽略了通过SetConfigurationBytes.

于 2013-11-27T05:57:20.377 回答
0

SetConfigurationBytes 确实有效。我构建了一个 XDocument 来表示 App.Config,如下所示

&lt;?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="TestProbingPath" />
</assemblyBinding>
</runtime>
</configuration>

XDocument doc=as above
MemoryStream stream = new MemoryStream();
doc.Save(stream);
byte[] configBytes = stream.ToArray();

请注意,stream.GetBuffer 将不起作用。

于 2014-03-14T15:30:35.067 回答