How do I transform replace a dependentAssembly in web config?

4.6k views Asked by At

So I'm trying to replace a dependentAssembly when someone adds my nuget package to their code.

The assembly I want to change is:

 <dependentAssembly>
    <assemblyIdentity name="Common.Logging.Core" publicKeyToken="af08829b84f0328e" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
  </dependentAssembly> 

Therefor I use this xml file and help from: Web.config transforms - the missing manual

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly xdt:Transform="Replace" xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name:'Common.Logging.Core')">
        <assemblyIdentity name="Common.Logging.Core" publicKeyToken="af08829b84f0328e" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="2.2.0.0" />
    </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

But I'm getting the error: An error occurred while applying transformation to 'web.config' in project: 'blabla' has an invalid qualified name.

In noticed when I change "Replace" to "Remove" it is removing the complete dependentAssembly but somehow afterwards it adds the same dependentAssembly to the web.config again. Maybe because Common.Logging.Core dependency get's added after the web.config transform?

And maybe is this the reason that the Replace isn't working?

2

There are 2 answers

0
TotPeRo On

The XML below applies a binding redirect to assemble Common.Logging.Core. It contains two transform operations. The first one ,InsertIfMissing, inserts a new entry if the assembly entry doesn’t exist, and the second one, Replace, replaces it in case the existing redirect already exist.

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1">
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly xdt:Transform="InsertIfMissing" xdt:Locator="Condition(asmv1:assemblyIdentity/@name='Common.Logging.Core')">
        <assemblyIdentity name="Common.Logging.Core" publicKeyToken="af08829b84f0328e" culture="neutral" xmlns="urn:schemas-microsoft-com:asm.v1"/>
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" xmlns="urn:schemas-microsoft-com:asm.v1"/>       
      </dependentAssembly>
      <dependentAssembly xdt:Transform="Replace" xdt:Locator="Condition(asmv1:assemblyIdentity/@name='Common.Logging.Core')">
        <assemblyIdentity name="Common.Logging.Core" publicKeyToken="af08829b84f0328e" culture="neutral" xmlns="urn:schemas-microsoft-com:asm.v1"/>
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" xmlns="urn:schemas-microsoft-com:asm.v1"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Pay attention at the namespace asmv1 added to the configuration element. It is needed for this to work.

NB: I wanted to avoid adding assemblyIdentity and bindingRedirect elements in the InsertIfMissing transform but couldn’t make it work. Let me know if you know how.

0
Emanuele Zambrano On

Try this:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <!-- first completely remove the parent element -->
      <dependentAssembly xdt:Transform="RemoveAll"
                         xdt:Locator="Condition(starts-with(./_defaultNamespace:assemblyIdentity/@name,'Microsoft.Diagnostics.Tracing.EventSource'))">
      </dependentAssembly>

      <!-- then add the new block -->
      <dependentAssembly xdt:Transform="Insert">
        <assemblyIdentity name="Microsoft.Diagnostics.Tracing.EventSource" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.1.16.0" newVersion="1.1.16.0 " />
      </dependentAssembly>

    </assemblyBinding>
  </runtime>