.netapp-configside-by-side

SideBySide Error with Binding Redirect in .net Windows Service


I have a .net windows service which needs to load two different versions of an assembly. It runs on a server 2012 R2 box. I am using a binding redirect in separate .config file which is loaded into the main app.config using this before the closing </configuration> node (see MSDN doc):

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <linkedConfiguration href="file://E:\my-service\runtime.config" />
</assemblyBinding>

My runtime.config contains the actual binding redirect:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
        <codeBase version="0.4.0.126" href="AutoMapper.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
        <codeBase version="3.2.1.0" href="AutoMapper.3.2.1\AutoMapper.dll" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>  
</configuration>

This works fine until the server is rebooted. We then see this in the event log after the machine starts:

Activation context generation failed for "Service.exe".
Error in manifest or policy file "Service.exe.Config" on line 71. 
The element assemblyBinding appears as a child of element configuration which is not supported by this version of Windows.

So I ran the sxstrace.exe tool (as per this blog) and get this output:

=================
Begin Activation Context Generation.
Input Parameter:
    Flags = 0
    ProcessorArchitecture = AMD64
    CultureFallBacks = en-US;en
    ManifestPath = E:\my-service\Service.exe
    AssemblyDirectory = E:\my-service\
    Application Config File = E:\my-service\Service.exe.Config
-----------------
INFO: Parsing Application Config File E:\my-service\Service.exe.Config.
    ERROR: Line 71: The element assemblyBinding appears as a child of element configuration which is not supported by this version of Windows.
ERROR: Activation Context generation failed.
End Activation Context Generation.

If I remove the linkedConfiguration from the main app.config the service starts (albeit with different errors). I can then add it back in and the service can be started and stopped fine until the machine is rebooted again.

Does anyone know why this would happen? And is this the correct use of the linkedConfiguration?

UPDATE

After and long and productive conversation with Microsoft support, I discovered that using the linkedConfiguration with an embedded manifest is not supported (see MSDN doc).

However there does appear to be a bug with loading the config from an external file. I have raised this as a bug on connect.


Solution

  • Following the update from Microsoft support and a suggestion from @cmckeegan, we moved away from an external config file for our binding redirect and moved it into code instead. We now call BindingRedirects.Register() in our composition root.

    The BindingRedirects class looks like this:

    public static class BindingRedirects
    {
        static readonly Dictionary<string, string> Redirects = new Dictionary<string, string>
        {
            { "AutoMapper, Version=3.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005", @"AutoMapper.3.2.1\AutoMapper.dll"}    
        }; 
    
        public static void Register()
        {
            AppDomain.CurrentDomain.AssemblyResolve += (o, args) =>
            {
                if (Redirects.ContainsKey(args.Name))
                {
                    var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Redirects[args.Name]);
                    return Assembly.LoadFrom(path);
                }
    
                return null;
            }; 
        }
    }