views:

299

answers:

2

Hi,

I have an application loader that dynamically loads applications. An application is an assembly with all of its dependents in a single folder. Using XCOPY deployment I can add/remove applications by copying/deleting a folder. To facilitate standard .NET assembly binding I copy the application folders under the bin of the loader. I set the probing privatePath in the config file and everything works like a charm.

The applications uses a framework, i.e. shared assemblies as dependents.

Now I have a requirement that states that each application has to be able to use its own version of the framework.

This works perfectly when I install the framework versions in the GAC, and the different versions of the assembly are loaded into the default AppDomain just fine.

Now I want to get back to my XCOPY solution and copy the correct framework versions in their corresponding application folders and the solution breaks.

The first application referencing its framework works fine, the second complains about not finding the assembly and the manifests not matching.

It's as if the .NET loader stops probing after a first match of the assembly with a folder in "privatePath" and does not look any further.

Any ideas on how to have the same behavior as when using the GAC? Anything else I could specify in config, codeBase? (no absolute file paths please).

kr, Michel

A: 

According to this article on Assemblies:

You should also remember that the CLR looks through a predetermined sequence of directories during probing. Given a privatePath value of MyAssemblies, the CLR will now probe for an assembly named MyLibrary in the following order:

C:/Apps/MyLibrary.DLL
C:/Apps/MyLibrary/MyLibrary.DLL
C:/Apps/MyAssemblies/MyLibrary.DLL
C:/Apps/MyAssemblies/MyLibrary/MyLibrary.DLL
C:/Apps/MyLibrary.EXE
C:/Apps/MyLibrary/MyLibrary.EXE
C:/Apps/MyAssemblies/MyLibrary.EXE
C:/Apps/MyAssemblies/MyLibrary/MyLibrary.EXE

The sequence of file paths in which the CLR probes for an assembly file is important because the probing process stops once the CLR locates an assembly file with the correct file name. If you deploy an application along with one version of MyLibrary.dll in the ApplicationBase directory and a second version in the subdirectory MyAssemblies, which DLL file will the CLR load? You should see that the CLR is going to load the DLL in the ApplicationBase directory because that is always the first directory searched by the CLR during the probing process.

Update:

Check this post. It deals with more or less the same problem you're having.

Yannick M.
Thanks.Furthermore if privatePath contains multiple folders, it seems the probing stops after the first folder in privatePath has been searched for, whether it found a version or not.I restate the question:Is it possible to make the probing process look for a referenced assembly in the same folder as the referencing assembly?If not, is it possible to make the probing process search for a matching assembly version accross all folders specified in privatePath?kr,Michel.
michel
A: 

You will have more luck if you use Assembly.LoadFrom to load all the assemblies you find in these folders.

This changes probing behaviour and allows the runtime to search locally to where the assembly was originally loaded from in order to find its references. You will get framework-version sharing at the assembly level, though.

That is:

  • App 'a' loads, causing Framework v1.02 to load.
  • App 'b' loads, causing Framework v1.01 to load.
  • App 'c' loads, linked to Framework v1.02, and simply reuses the code that was loaded after App 'a' was loaded.

that said - this solution might be of no use if you're not explicitly loading the assemblies.

In that case - I'd go with the solution in the answer mentioned by Yannick M. - hook into the AssemblyResolve event; store some static state as you begin to load an app so your event handler knows which app is loading; and if any Assembly fails to resolve, you can look at this state to determine where it should be looking and load the assembly from there.

Andras Zoltan