How to update AssemblyBinding section in configuration file at runtime?

I am trying to change the assembly binding (from one version to another) dynamically.

I tried this code but it does not work:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); ConfigurationSection assemblyBindingSection = config.Sections["assemblyBinding"]; assemblyBindingSection.SectionInformation.ConfigSource = "bindingConf.xml"; config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("assemblyBinding"); 

with bindingConf.xml containing the assembly section configuration.

So, is it possible to change this section at runtime? how to do it? What are my alternatives?

+6
c # configuration
source share
2 answers

The best way I've found to dynamically bind to a different version of an assembly is to bind the AppDomain.AssemblyResolve event. This event is fired whenever the runtime cannot find the exact assembly that the application was associated with and allows you to provide another assembly that you download yourself (as long as it is compatible).

For example, you can put a static constructor in the main class of the application, which intercepts the event as follows:

 using System.Reflection; static Program() { AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) { AssemblyName requestedName = new AssemblyName(e.Name); if (requestedName.Name == "AssemblyNameToRedirect") { // Put code here to load whatever version of the assembly you actually have return Assembly.LoadFrom("RedirectedAssembly.DLL"); } else { return null; } }; } 

This method avoids the need to deal with assembly bindings in configuration files and is more flexible in terms of what you can do with it.

+17
source share

RuntimeSection updates the configuration file at run time with this code:

 private void ModifyRuntimeAppConfig() { XmlDocument modifiedRuntimeSection = GetResource("Framework35Rebinding"); if(modifiedRuntimeSection != null) { Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); ConfigurationSection assemblyBindingSection = config.Sections["runtime"]; assemblyBindingSection.SectionInformation.SetRawXml(modifiedRuntimeSection.InnerXml); config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("runtime"); } } 

with Framework35Rebinding containing:

 <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.CompactFramework.Build.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="9.0.0.0"/> </dependentAssembly> </assemblyBinding> </runtime> 

and app.config containing (before program execution):

 <?xml version="1.0"?> <configuration> <startup> <supportedRuntime version="v2.0.50727"/> </startup> <runtime> </runtime> </configuration> 

However, this does not work for what I want to do, because assemblyBinding is only read when the application starts, whereas RefreshSection("runtime")

+3
source share

All Articles