35

If A references assembly B 1.1 and C, and C references B 1.2, how do you avoid assembly conflicts?

I naively assumed C's references would be encapsulated away and would not cause any problems, but it appears all the dll's are copied to the bin, which is where the problem occurs.

I understand the two ways around this are to use the GAC or assembly bindings? The GAC doesn't seem like the best approach to me, as I don't like assuming dlls will be there, I prefer to reference dlls from a lib directory in my solution.

Where as assembly bindings don't seem robust to me, what if one version of the assembly has functionality that the other doesn't, will this not produce problems?


In my case its because I'm using a 3rd party dll uses a older version of nHibernate, than I'm using myself.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Dan
  • 29,100
  • 43
  • 148
  • 207
  • I think you have a typo in the title there. "same different" should probably just be "different". :) – Herms Oct 21 '08 at 19:42

5 Answers5

9

I've achieved the same results using the GAC in the past, but you should question your reasons for having to reference more than one version and try to avoid it if possible. If you must do it, a binding redirect may help in your case.

Also, have you read this yet?

Kilhoffer
  • 32,375
  • 22
  • 97
  • 124
6

A seemingly little known way of doing this is to use the extern keyword.

From C# Reference

To reference two assemblies with the same fully-qualified type names, an alias must be specified at a command prompt, as follows:

/r:GridV1=grid.dll

/r:GridV2=grid20.dll

This creates the external aliases GridV1 and GridV2. To use these aliases from within a program, reference them by using the extern keyword. For example:

extern alias GridV1;

extern alias GridV2;

Each extern alias declaration introduces an additional root-level namespace that parallels (but does not lie within) the global namespace. Thus types from each assembly can be referred to without ambiguity by using their fully qualified name, rooted in the appropriate namespace-alias.

In the previous example, GridV1::Grid would be the grid control from grid.dll, and GridV2::Grid would be the grid control from grid20.dll.

Peter Kelly
  • 14,253
  • 6
  • 54
  • 63
  • 4
    So, how do you use that, practically? What command prompt is this, and how can it be integrated in a build process? – Nyerguds Mar 21 '13 at 07:57
  • 2
    This works fine except that providers generally don't change the name of the dll from version to version so you end up trying to reference two assemblies with the same name. Studio doesn't like that and non-deterministically copies one of those to the output folder so this only works if dlls have different names by version. – Jay Walker Apr 24 '13 at 21:01
3

I was required to support multiple versions of an assembly and found this solution:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="MyAssembly" publicKeyToken="..." />
        <codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/>
        <codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

Add this in app.Config.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
burton
  • 31
  • 1
2

You can add a bindingRedirect element to your configuration file to specify which version of the assembly you want to use at runtime.

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>
Joe
  • 122,218
  • 32
  • 205
  • 338
  • 4
    Yeah I mentioned that in my question, I asked what happens in the case where there is different functionality in the assemblies? – Dan Oct 22 '08 at 08:06
1

The .NET runtime is perfectly capable of loading multiple versions of the same assembly simultaneously. If you are going to open this can of worms, however, I strongly suggest you stronly name your assemblies and use the Major.Minor.* naming scheme to avoid naming conflicts.

I don't think you should think of a one-size-fits-all approach to using (or not) the GAC. The GAC can be really nice if you want to automagically use new functionality published with future versions of a DLL. Of course, this blessing comes at a cost that new versions might not work exactly like you expect them too :). It's all a matter of what's most practical, and how much control you have over what gets published to the GAC.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
AlanR
  • 1,162
  • 4
  • 14
  • 26