如何获得AppDomainSetup.SetConfigurationBytes()工作?

时间:2013-11-27 04:33:07

标签: c# .net appdomain appdomainsetup

在我的应用程序中,我正在创建沙箱域,我需要动态定义绑定重定向规则。但是,我无法使用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继承,以编组调试到子appdomain的DebugPrint,而不是在当前域中创建的副本上调用(感谢sthotakura)。 因此,ConfigurationFile设置开始工作。但是SetConfigurationBytes仍然没有运气。无论如何,目标是定义bindingRules,如果通过SetConfigurationBytes传递,它将起作用。

2 个答案:

答案 0 :(得分: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 Method

  

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

因此,我怀疑,System.Configuration命名空间中的类型(如ConfigurationManager)忽略了通过SetConfigurationBytes提供的配置数据。

答案 1 :(得分:0)

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

<?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不起作用。