在我的应用程序中,我正在创建沙箱域,我需要动态定义绑定重定向规则。但是,我无法使用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传递,它将起作用。
答案 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不起作用。