Here would be a followup to this issue you raised.
Basically, the behavior we encounter here is normal.
Regarding the above, it was indeed the correct approach in our case. However, you mentioned that subsequent upgrades after that will duplicate the element, which is indeed true. Here, we need to take into consideration that these XML operations are like an update to the respective XML file, therefore the element being duplicated is normal.Basically, during the update, the setup will find the first "dependentAssembly" element, which in our case is:
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
and update it, resulting in:
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
To avoid this, please use the following option instead: "If the element is found" --> "Add a new sibling" (as in my screenshot above)
To avoid that behavior, in the next version, we should "reset" the last added element to have the same options as the other 3 (e.g from "If the element is found" --> "Add a new sibling" to "If the element is found" --> "Update"). Of course, the same should be done with the child elements as well.
Hope this helps!
Best regards,
Catalin