2

I have an API DLL that several third party applications reference.

Some of these applications want things two ways in terms of updates. 1) I want the latest stuff 2) Don't update my direct binaries that often

There has been the thought of moving the DLL into the GAC and writing another DLL that is simply the wrapper for the DLL in the GAC (which the 3rd party apps would then reference). This allows the business logic (the part that would change frequently) to be updated in the GAC and the wrapper DLL would only need to be updated when new functions were made available.

The GAC is intended to keep versioned DLLs. So the wrapper DLL would have a reference to a specific version of the API DLL. How difficult is it to update the GAC DLL so that the references to it don't break but the binary contents differs?

Is this as simple as not changing GAC DLL versions when updating?

Thanks.

byanity
  • 203
  • 1
  • 4
  • 14
  • I would avoid the GAC if you possibly can, in favour of copying DLLs to each application where they're used. The GAC introduces an extra level of fragility into your development process (e.g. see my answer below). Because GAC DLLs supercede local copies -- at build time and at run time -- you can never quite be sure of what DLL version you're going to get. – Tim Robinson Aug 23 '10 at 12:33

4 Answers4

3

How difficult is it to update the GAC DLL so that the references to it don't break but the binary contents differs?

You can't do it directly. You can only put signed DLLs into the GAC. When you build your app against a signed DLL, the compiler takes a hash of the contents of the DLL and puts it in the app. When the .NET runtime loads the app, it checks this hash against the real copy of the DLL. If this DLL doesn't match the one you built with, .NET throws an exception.

The way to work around this is to:

  1. Put in place a version numbering scheme for your GAC DLL. This can be as straightforward as always incrementing the version number when you do a build.
  2. In your app.config, add a <bindingRedirect> element

In effect a binding redirect says, "if you're looking for a DLL with version numbers in the range 1.x to 1.y, look at version 1.z instead".

Edit: There are ways round the .NET strong name integrity check, but I recommend designing your application around the standard strong name mechanism before trying to circumvent it.

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
  • Do you have a reference to information that hashes are involved in all cases? – Eugene Mayevski 'Callback Aug 23 '10 at 12:35
  • I'm answering from day-to-day experience, but I can consult Google. – Tim Robinson Aug 23 '10 at 12:36
  • Here's a decent explanation, with a link to MSDN: http://ianpicknell.blogspot.com/2010/02/tampering-with-strong-named-assembly.html – Tim Robinson Aug 23 '10 at 12:44
  • Looks like strong-name binding uses only version number and public key token, not assembly hash. This corresponds to my experience, and this is the reason I asked about references. I.e. you can replace the assembly in GAC if it is strongnamed and has the same version number. – Eugene Mayevski 'Callback Aug 23 '10 at 12:48
  • Even if you set bypassTrustedAppStrongNames="false", as per the bottom of the blog post? – Tim Robinson Aug 23 '10 at 12:53
  • Again from my experience, strong naming includes check for version + sn_key hash, not assembly hash. Maybe key hash is what you mean by "hash", isn't it? What I am trying to say is that after recompilation of the assembly you can easily replace the assembly in the GAC with the new build, if you keep version number and the same sn key. This is for sure, we sometimes give custom builds to the customers this way. – Eugene Mayevski 'Callback Aug 23 '10 at 13:09
  • @Eugene, maybe better to add this as a separate answer. It sounds like you're doing what the OP wants to, and you're suggesting something different from me. – Tim Robinson Aug 23 '10 at 13:22
2

You can create an updated assembly, sign it and push it to the GAC so that the applications, which reference this assembly, won't notice the difference. You need to specify all parts of the version number (i.e. have the version number as 1.2.3.4 and not 1.2.3.* in AasemblyInfo.cs file) and use the same sn key. Then the version-specific reference won't be broken. And you'll be able to update your DLL as you need.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
2

I use Windows Installer to deploy my assemblies to the GAC. From a servicing perspective it's important to understand the difference between:

[AssemblyVersion]

and

[AssemblyFileVersion]

The former is considered as part of the strong name contract / binding while the latter is not. Additionally the latter is considered by Windows Installer in terms of deciding to overwrite the file or not during an upgrade.

Botton line: If your changes to the assembly doesn't break interfaces or cause any behavior regressions, you can keep the AssemblyVersion the same and increment AssemblyFileVersion and redeploy.

This is how .NET Framework Service Packs work as Microsoft has to be able to service the base class libraries without breaking applications that have existing SN references.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
1

References can include version information or reference whatever version is available. This is determined by the author of the application that references your DLL. Of course, you can ship your updated DLL as having the same version as in the GAC, but the whole point of versioning stuff is to let all parties handle updates correctly. So you might need to refine your task.

joekoyote
  • 221
  • 1
  • 5