nair_anup
asked on
Calling multiple assembly versions from same assembly
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
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
ASKER
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks a lot Vasco,
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.W
return System.Reflection.Assembly
}
}
}
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.CreateI
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=1d741a824a1
"lib2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1
"lib3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1
};
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=1d741a824a1
lib2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1
lib3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=1d741a824a1
(on my machine)
so, this demonstrates calling multiple assembly versions from within the same app.
hth
Vasco