Solved

Calling multiple assembly versions from same assembly

Posted on 2004-04-18
4
541 Views
Last Modified: 2008-02-01
Hi All,

I have made a dot net dll of different versions i.e, version 1.0.0.1, 2.0.0.1, 3.0.0.1 and have successfully registered them all in the GAC. The GAC shows me all the 3 versions.

Now I have to call all the three separate versions of the dlls from the same assembly. If I do "an reference" it only calls the last versioned dll that was compiled.

The idea is how do I specifically call the dll of version 1.0.0.1.

A code sample would be very helpful.

Thanks in advance.
AN
0
Comment
Question by:nair_anup
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 12

Expert Comment

by:vascov
ID: 10864561
Hi, this sample might seem a bit complicated but it illustrates the point.
You can only have one version of a given assembly per appdomain, therefore to have multiple assembly version loaded in the same process, you'll have to load them in different (new) appdomains.
If at all times, you'll be calling only a specific version, then you can opt for assembly binding at the config file level (look for assemblyRedirect).

Now, supposing you want to call different versions of the assembly in the same process space, here goes a sample:
We'll start with the interface that we'll share across the versions (it doesn't specifically need to be an assembly...)
// ilib.cs
using System;
using System.Reflection;

[ assembly: AssemblyKeyFile( @"yourKeyFile.snk" ) ]

namespace MyLib
{
        public interface IMyClass
        {
                string MyMethod();
        }
}

save this file as yourKeyFile.snk. (i'm assuming there's a yourKeyFile.snk ... if you don't have, generate one using sn -k)

Next, let's implement our lib:
// lib.cs
using System;
using System.Reflection;

[ assembly: AssemblyKeyFile( @"yourKeyFile.snk" ) ]
#if (V1)
[ assembly: AssemblyVersion( "1.0.0.0" ) ]
#elif (V2)
[ assembly: AssemblyVersion( "2.0.0.0" ) ]
#else
[ assembly: AssemblyVersion( "3.0.0.0" ) ]
#endif

namespace MyLib
{
      [ Serializable ]
      public class MyClass : IMyClass
      {
            public string MyMethod()
            {
                  System.Diagnostics.Debug.WriteLine( System.Reflection.Assembly.GetExecutingAssembly().FullName );
                  return System.Reflection.Assembly.GetExecutingAssembly().FullName;
            }
      }
}

Now, let's build our app:
// app.cs
using System;
using System.Reflection;
using System.Diagnostics;


class AppLauncher
{
      public AppLauncher( string AssemblyName )
      {
            // Create AppDomain
            AppDomain ad = AppDomain.CreateDomain( AssemblyName );
            Debug.Assert( null != ad );                  

            // Load Assembly
            Assembly asm = ad.Load( AssemblyName );
            Debug.Assert( null != asm );
            
            // Create Instance & GetProxy to object
            MyLib.IMyClass o = (MyLib.IMyClass)ad.CreateInstanceAndUnwrap( AssemblyName, "MyLib.MyClass" );
            Debug.Assert( null != o );
            
            // Execute the method
            Console.WriteLine( o.MyMethod() );

            // Drop the AppDomain
            AppDomain.Unload( ad );
      }
}

class app
{
      public static void Main()
      {
            string[] v = {
                  "lib1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1352f7",
                  "lib2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1352f7",
                  "lib3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1352f7"
            };
      
            foreach( string test in v )
            {
                  try
                  {
                        new AppLauncher( test );
                  }
                  catch( Exception e )
                  {
                        Console.WriteLine( "Error executing {0}\n{1}", test[1], e.ToString() );
                  }
            }
      }
}

Now, you'll have to find out the publickeytoken of your dll (sn -Tp lib1.dll)

To help you building everything, the following makefile may help you (makefile):
all: lib1.dll lib2.dll lib3.dll app.exe

clean:
        del *.dll
        del *.pdb

deploy: lib1.dll lib2.dll lib3.dll ilib.dll
        gacutil -i ilib.dll
        gacutil -i lib1.dll
        gacutil -i lib2.dll
        gacutil -i lib3.dll

undeploy: lib1.dll lib2.dll lib3.dll ilib.dll
        gacutil -u lib1
        gacutil -u lib2
        gacutil -u lib3
        gacutil -u ilib.dll

ilib.dll: ilib.cs
        csc /t:library /out:ilib.dll ilib.cs

lib1.dll: lib.cs ilib.dll
        csc /D:V1 /t:library /out:lib1.dll lib.cs /debug+ /r:ilib.dll

lib2.dll: lib.cs ilib.dll
        csc /D:V2 /t:library /out:lib2.dll lib.cs /debug+ /r:ilib.dll

lib3.dll: lib.cs ilib.dll
        csc /D:V3 /t:library /out:lib3.dll lib.cs /debug+ /r:ilib.dll

app.exe: app.cs ilib.dll
        csc /debug+ app.cs /r:ilib.dll

Now, just do:
nmake
nmake deploy

then you can do:
nmake clean

and finally

app.exe, which will produce:
lib1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1352f7
lib2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1352f7
lib3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1352f7
(on my machine)

so, this demonstrates calling multiple assembly versions from within the same app.

hth

Vasco
0
 

Author Comment

by:nair_anup
ID: 10868238
Thanks  vascov,

The code was of great help.
My problem is calling the 1.0.0.1 version of the dll which is there registered in the gac but the physical location at which it is compiled is version 3.0.0.1,

So when I do Add reference i get the latest version.

can I obtain the older versions without using the AppDomain call.

This help would be greatly appreciated.

Thanks,
AN
0
 
LVL 12

Accepted Solution

by:
vascov earned 150 total points
ID: 10868631
If you have an assembly handy, you can link to it and it will be used. (there's a way to go mucking for the assembly in the GAC, but i would recommend you to use the previously generated assembly)

The other option is to use config file to rebind to a previous version of your assembly. Provided that the API is the same it shoud work.

Something like this:
<configuration>
      <runtime>
            <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
                  <dependentAssembly>
                        <assemblyIdentity
                              name="lib"
                              publicKeyToken="1d741a824a1352f7"
                                          culture="neutral" />
                        <bindingRedirect oldVersion="3.0.0.0"
                              newVersion="1.0.0.0"/>
                  </dependentAssembly>
            </assemblyBinding>
      </runtime>
</configuration>

hth

Vasco
0
 

Author Comment

by:nair_anup
ID: 10868667
Thanks a lot Vasco,
0

Featured Post

[Webinar] Learn How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them. Thursday, July 13, 2017 10:00 A.M. PDT

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

628 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question