C# 如何使AppDomainSetup.SetConfigurationBytes()工作?

C# 如何使AppDomainSetup.SetConfigurationBytes()工作?,c#,.net,appdomain,appdomainsetup,C#,.net,Appdomain,Appdomainsetup,在我的应用程序中,我正在创建沙盒域,我需要动态定义绑定重定向规则。但是,我无法使用SetConfigurationBytes方法传递ConfigurationFile设置或原始xml数据 我创建了一个示例来检查配置数据是否应用于子域: var configData = @"<?xml version='1.0' encoding='utf-8' ?> <configuration> <appSettings> <add key='MyData

在我的应用程序中,我正在创建沙盒域,我需要动态定义绑定重定向规则。但是,我无法使用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();
更新 上面代码的第一个问题是,它必须从MarshallByRefObject继承,以封送DebugPrint调用到子appdomain,而不是调用在当前域中创建的副本(感谢sthotakura)。
因此,ConfigurationFile设置开始工作。但是SetConfigurationBytes仍然没有成功。无论如何,我们的目标是定义bindingRules,如果通过SetConfigurationBytes传递,它就可以工作。

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

从第页开始:

使用类型时,类型必须从MarshalByRefObject继承 跨越应用程序域边界,对象的状态必须 无法复制,因为对象的成员在外部不可用 创建它们的应用程序域

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

[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("=====================================");
    }
}
我在一个示例应用程序中进行了尝试,但使用了配置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页面

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


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

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();

XDocument doc=如上所述
MemoryStream stream=新的MemoryStream();
单据保存(流);
byte[]configBytes=stream.ToArray();

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

很好!我刚才问的是SetConfigurationBytes()。@olegz好的,那么您想替换新AppDomain的配置位,而不是为新AppDomain提供新配置?@olegz看起来似乎忽略了通过SetConfigurationBytes传递的任何内容:(@olegz在您的原始问题中,您还提到您也无法通过
ConfigurationFile
,因此此答案是您的一个选项。ConfigurationFile确实有效,谢谢。SetConfigurationBytes不可用:)
<?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();