Loading the Same Assembly with Different Evidence
Assembly.Load provides overloads that take an Evidence object in addition to the name of the assembly to load. This leads to the question -- what happens if you were to load the same assembly multiple times with different Evidence.
It's easy enough to figure that out with a few lines of code:
Evidence myComputer = new Evidence(
new object[] { new Zone(SecurityZone.MyComputer) },
new object[] { });
Evidence intranet = new Evidence(
new object[] { new Zone(SecurityZone.Intranet) },
new object[] { });
Assembly intranetAsm = Assembly.Load("TestAssembly", intranet);
Assembly myComputerAsm = Assembly.Load("TestAssembly", myComputer);
Console.WriteLine(
"myComputerAsm ReferenceEquals intranetAsm? {0}",
Object.ReferenceEquals(myComputerAsm, intranetAsm));
Console.WriteLine();
Console.WriteLine("myComputerAsm Evidence");
foreach(object o in myComputerAsm.Evidence)
if(o is Zone)
Console.WriteLine(o);
Console.WriteLine();
Console.WriteLine("localIntranetAsm Evidence");
foreach(object o in intranetAsm.Evidence)
if(o is Zone)
Console.WriteLine(o);
This program loads TestAssembly twice, first with evidence saying it came from the intranet, and then with evidence saying it belongs to the MyComputer zone. After loading the assembly, we then check to see if we've got the same Assembly instance from each load, and dump out any Zone evidence that we find.
Running this program shows:
myComputerAsm ReferenceEquals intranetAsm? True
myComputerAsm Evidence
<System.Security.Policy.Zone version="1">
<Zone>Intranet</Zone>
</System.Security.Policy.Zone>
localIntranetAsm Evidence
<System.Security.Policy.Zone version="1">
<Zone>Intranet</Zone>
</System.Security.Policy.Zone>
The results may be somewhat surprising. Even though we explicitly specified that the assembly be loaded with two different sets of evidence, we actually ended up with the exact same Assembly objects. Obviously, since they were the same objects, they also both have the same Evidence which matches the first Evidence we applied.
Why is this? Well, an assembly can only be loaded once into each AppDomain. The CLR doesn't support the concept of having two copies of an assembly floating around a domain with different grant sets. Given that an assembly can only be loaded once, the Evidence is applied and evaluated for the first Load; further attempts to load the same assembly just return the already loaded version without evaluating policy.
Why doesn't the CLR notice that the evidence objects are different and throw an exception warning the user? There's actually no real good way for us to do that. Since Evidence is basically just a collection of Object, we have no way of compelling any object that's being used as evidence to create a useful override of Equals. That means internally the CLR doesn't have a good way of actually determining if two sets of Evidence are equivalent or not. Using the default Equals implementation won't work, since we don't want to disallow loading an assembly twice with different instances of equivalent evidence objects.
All that being said, remember that assemblies can in fact have different permission sets in different AppDomains. So if you really want to have an assembly be loaded into your process with multiple grant sets, you'll just need to ensure that each time you load the Assembly with a new grant set you place it in a new AppDomain.
Comments
Anonymous
July 21, 2005
The comment has been removedAnonymous
July 25, 2005
The comment has been removedAnonymous
February 27, 2007
I have a problem with loading assemblies of plug-ins at runtime because they relate to some of the assemblies of the main application which have a slightly newer version. E.g. We have some plug-ins (running also in the main AppDomain because they are well known and installed by an administrator) which are compiled against say version 1.0.0.0 of the Hostapplication. Now if we replace the host application through 1.0.0.1 the plug-ins fail to load because they expect to find version 1.0.0.0 of a referenced assembly. Any ideas what I have to change that the plug-ins automatically take the assembly version that is loaded? Can I emit a publisher policy at runtime as I know which assemblies are loaded and have the old assemblies in hands (as binary and reflection-only assemblies)? Thanks for any help ChrisAnonymous
February 27, 2007
Hi Chris, The AddIn team is doing a lot of work to enable AddIns and hosts to version independently of each other. You might want to check out their blog here: http://blogs.msdn.com/clraddins/ for more information on their versioning solution. -ShawnAnonymous
February 28, 2007
Great, that seems to be exactely the right blog for me. Thanks you and bye Chris