tags:

views:

560

answers:

2

Hi

I am loading an assembly in C# using reflection:

Assembly = Assembly.Load([assembly_bytestream]);

The assembly being loaded references another two assemblies. To my understanding reflection will load the main assembly and then search the GAC for the referenced assemblies, if it cannot find it there, you can then incorparate an assemblyResolve event:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
  if (args.Name.IndexOf([refAsm]) > -1)
  {
    Assembly shdocvw = Assembly.LoadFrom([dllPath]);
  }
}

The thing is, I dont want to first look in the GAC I want to force reflection to load the reference assemblies from a specific path I define. Any ideas on how to do this?

+3  A: 

You could load the dependent assemblies yourself before loading the one that requires them.

SLaks
Hi SlaksAre you saying that reflection would check the memory stream before checking the GAC?
Yo Momma
If the assembly is already loaded, it won't try to load it again.
SLaks
Sounds simple enough. I will try this out. Thanks
Yo Momma
Hey Slaks, You helped point me in the right direction. I did it afterwarda though. Basically first loaded the main assembley:Assembly asm = Assembly.Load([assembly_bytestream]);and then got all the references and loop through them looking out for the specific oines I wanted loaded from a specific location instead of the GAC:AssemblyName[] references = asm.GetReferencedAssemblies();foreach (AssemblyName asmName in references){ if (asmName.FullName.Contains([name_of_ref_asm])) { Assembly shdocvw = Assembly.LoadFrom([dllPath]); }}
Yo Momma
+5  A: 

To my understanding reflection will load the main assembly and then search the GAC for the referenced assemblies

Correct, but another important detail: the framework will look in the app domain's search path before looking in the GAC. Normally the app domain search path consists of just the directory in which the main EXE is located, although you can configure your app to look in specific subdirectories too, either via app.config, or by starting a second app domain and configuring it programmatically.

Where are your referenced assemblies located relative to your app's EXE?

Edit: I always refer to Suzanne Cook's assembly load cheat sheet when debugging issues like this. The rest of her blog is full of similarly useful information.

Tim Robinson
Well it's a ClickOnce application so the exe sits under the users ClickOnce cache in the apps folder. The clickOnce application calls a web service which passes down a bytestream(the assembly in question). The referenced assemblies of the assembly in question sit in the apps folder.
Yo Momma
So what's the specific path you want to look in? The original ClickOnce location? If so, this should already work. If it's not working, it would be helpful to see the fusion log attached to the exception triggered by the assembly failing to load.
Tim Robinson
The assembly does load successfully, but it loads from the gac. I want to specify the path.
Yo Momma
Which path - the ClickOnce deployment directory? If so, you've got an assembly with the same name, version number, public key token and name deployed in both your application's directory and the GAC. Aren't they the same binary?
Tim Robinson
...to rephrase my last question: if they're not the same binary, why do they have the same name, public key token and version number? Or have I misunderstood your situation?
Tim Robinson
Perhaps you are misunderstanding it a tad. The assembly is being Loaded in Runtime. You have a host application(the clickonce app), which loads assemblies at runtime. Assemblies built at runtime are not physically present on a clients machine, they are sent through web services as bytestream and sit in memory. The reference assemblies however sit on the clients pc. They dont have the same names or binaries
Yo Momma
The in-memory assemblies aspect is straightforward. What I'm not clear on is where the reference assemblies are located: they're in the GAC, and they're also somewhere else. I'm not clear on where the 'somewhere else' is.
Tim Robinson
The referenced assemblies are a microsoft component, for isntance, lets take good old IE. mshtml.dll is already in the GAC in some instances. I create an interop that gets installed with the ClickOnce App in the ClickOnce folder, and I want to reference that .dll instead of the one in the GAC, due to different machines having different versions of the dll
Yo Momma
In which case it's probably safer to generate your own interops from the command line (using TlbImp.exe) and giving them a specific name and/or signing them with your own private key. In particular, if you give them your own private key, they're guaranteed not to conflict with anybody else's assemblies.
Tim Robinson