Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Popular open source libraries and reference conflicts

We use log4net in all of our (many) in-house applications. We typically do what amounts to xcopy deployment. For developer convenience, we compiled the log4net source into one of our core libraries.

This is now coming back to bite us. Other open-source libraries (such as Topshelf) reference log4net. Still others (NServiceBus, for example) merge log4net into their assemblies. Usually the versions differ.

This is a general question; the specific libraries are just examples.

There are several similar questions:

  • The located assembly's manifest definition does not match the assembly reference
  • .Net picking wrong referenced assembly version
  • How do I resolve ambiguity between my project DLL and a DLL in the GAC?
  • .NET compiled third-party DLL reference conflict

Of the various solutions (GAC, assemblyBinding, bindingRedirect, etc.), what is likely to cause us the least pain in the future? We can modify our core library; we just can't do anything that would break an existing deployed version in the field. Updating all of our project references will be painful, so we only want to do this once.

Update: The current version of Topshelf abstracted logging, so this is no longer an issue with that framework.

like image 568
TrueWill Avatar asked Nov 17 '11 22:11

TrueWill


2 Answers

In your case, I would deploy my DLL in the GAC with a Publisher Assembly Policy

A publisher policy assembly is an assembly that configures the policy to be used when the .NET runtime binds to an assembly. So you can easily update all your project by specifying in the publisher policy which version of your DLL must be used.

Sample of a publisher assembly policy:

<configuration> 
<runtime>
 <assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
  <dependentAssembly> 
   <assemblyIdentity name=”website” publicKeyToken=”18517ea673f8584b” culture=”neutral” />
   <bindingRedirect oldVersion=”1.0.0.0″ newVersion=”2.0.0.0″/> </dependentAssembly> 
</assemblyBinding> 
</runtime> 
</configuration>
like image 140
Steven Muhr Avatar answered Sep 28 '22 22:09

Steven Muhr


One little known/used feature that I consistently to deal with multiple references, and help easily upgrade them is Reference Paths in combination with Binding Redirects. Using reference paths, I'm able to maintain a shared library, in a separate class-library/package in source control, that contains the dependent library we're using.

Having my own copy of the files, seperately controlled (often needing to include a .license file in the shared libraries folder as well if it's a paid library), allows new developers to quickly ensure they have the right version installed on their machine, without conflicting with the existing libraries already on your machine.

There is a caveat to this approach, and that is any additional reference paths you add are not stored in the .csproj file, but instead, the .csproj.user file.

In many out-of-the-box source control solutions, such as Team Foundation Server, or Vault; these files, by default are not included in the check-in process. Most source control providers, including the two mentioned though have an option for changing controlled file extensions per-project, as well as globally.

The only other caveat is some source control providers, such as Vault, treat .csproj and .csproj.user files as binary files by default; again, this can be changed, and they can be treated as XML in Vault's case, allowing merges to be made.

They are treated as XML out-of-box in Team Foundation Server.

like image 43
Brian Deragon Avatar answered Sep 28 '22 23:09

Brian Deragon