9

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:

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.

Community
  • 1
  • 1
TrueWill
  • 25,132
  • 10
  • 101
  • 150
  • 1
    Just FYI you can quite easily automatically process `.proj` files, they're just MSBuild scripts. I understand that you don't want to dot his, but it's not too too painful. – Joe Nov 17 '11 at 22:41
  • @Joe - really good idea! They're just XML. – TrueWill Nov 17 '11 at 22:56
  • Beware, VS doesn't write MSBuild files the way you would write MSBuild files. – Joe Nov 17 '11 at 23:51
  • @Joe - we'd add the reference to one project in VS, check the diffs, then use an XML parser to insert that same reference in the same area in other projects. Any major risks in that? – TrueWill Nov 18 '11 at 00:27
  • 1
    I can only say try it and run it back through VS a few times. IIRC it saves the project trees into MSBuild format, then parses the MSBuild format back into this tree when the time comes to save. So it may mangle any given input. It's been a while since I did it, but I remember it being fine inserting variables in interesting places, but the VS did something weird if you tried to make changes to the same thing with the GUI. Sorry, can't be less vague than that! – Joe Nov 18 '11 at 00:41

3 Answers3

1

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.

Brian Deragon
  • 2,929
  • 24
  • 44
  • 1
    +1. For awhile we checked in .csproj.user to share the Start Action on the Debug tab, but that caused issues (especially when our paths changed due to branching). – TrueWill Nov 22 '11 at 15:33
  • Good point, that can be alleviated somewhat, but it is a headache. – Brian Deragon Nov 22 '11 at 16:12
  • 1
    I guess your other option, is hosting a custom NuGet package, and checking in the package file...a little bit of upfront work, but it's built in. – Brian Deragon Nov 22 '11 at 16:14
1

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>
svick
  • 236,525
  • 50
  • 385
  • 514
Steven Muhr
  • 3,339
  • 28
  • 46
0

There is an NServiceBus which doesn't merge 3rd-party assemblies.

From the download page:

Problems with merged assemblies?

In order to decrease the number of assemblies developers need to reference in their Visual Studio projects, NServiceBus merges several third-party assemblies into its own assemblies. This may cause conflicts if developers are using those third-party assemblies in their own code - specifically when using a different version than that which came with NServiceBus.

In order to resolve this problem, developers should use the "core-only" assemblies of NServiceBus. For companies that have purchased a commercial NServiceBus license and support package, these assemblies can be found in the "core-only" directory.

If you're using the express edition, you'll need to pull down the source (above) and compile it yourself using the "UnsupportedBuildCoreOnly.bat" file.

Craig Stuntz
  • 125,891
  • 12
  • 252
  • 273
  • Thanks; I had read that. We aren't actually using NServiceBus (we evaluated it); that was just an example. – TrueWill Nov 17 '11 at 22:34
  • Craig, while I realize your answer may be helpful for those using NServiceBus, if you edit it to address the general question you'll have a shot at that 100 rep. :) – TrueWill Nov 21 '11 at 21:07