Why doesn't private assembly discovery use the Fully Qualified Assembly Name to match, but rather the filename?
Our application dynamically loads a set of private assemblies that each reside under their own sub-directory. They each have their own dependencies which are also in that same sub-directory. Each assembly is strongly named and the dependencies are the same library, but different versions.
MyApp
|-> Folder1\
| |->PrivateAssembly1.dll
| |->Dependency.dll Version 1.0.0.0
|
|-> Folder2\
| |->PrivateAssembly2.dll
| |->Dependency.dll Version 2.0.0.0
|
...
Since we're doing xcopy deployment so we don't use the GAC.
We also have probing privatePath
defined to "Folder1;Folder2"
to solve any issue of not finding the private assemblies.
The problem is that PrivateAssembly1.dll seems to find its dependency, but PrivateAssembly2.dll does not. Or rather, it seems to be trying to use Dependency.dll from Folder1 in stead of Folder2.
I know these issues can be manually resolved by using the AssemblyResolve event, however this isn't the cleanest approach. Are there other solutions I am overlooking?
Thanks for any and all ideas.
Update:
The output of the Fusion Log tool:
LOG: DisplayName = Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=#########
(Fully-specified)
LOG: Appbase = file:///C:/Workspaces/Shell/MyApp/bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
...
LOG: Attemp开发者_如何学编程ting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Dependency.DLL.
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Dependency/Dependency.DLL.
LOG: Attempting download of new URL file:///C:/Workspaces/Shell/MyApp/bin/Folder2/Dependency.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Workspaces\Shell\MyApp\bin\Folder2\Dependency.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Dependency, Version=2.0.0.0, Culture=neutral, PublicKeyToken=#######
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
So basically, it finds a Dependency.dll in Folder2, attempts to Load it only to see that the version doesn't match. I would assume it would try Folder1 next, but it just stops there...
First thing to do is use the Fusion Log Viewer "FUSLOGVW.exe
"1 to enable logging of assembly loading. This will show you where the CLR is trying to load the dependencies from. This should confirm some location is missing—and tell you what you are missing in your .config
.
[Edit: Now with log]
Once a matching assembly name has been found, no more (file) search takes place. I.e. keep your assembly names unique.
(This is similar to C++ method overload resolution, first the best match is found and then accessibility is checked, so a weaker parameter match that is accessible will not be considered.)
1 NB. If you are running on a 64bit system, thee are separate 32 and 64bit versions of this tool: ensure you use the right one.
The reason why .NET objects to this is that you are trying to load different versions of the same assembly into the appdomain. You have to decide if you can let PrivateAssembly1.dll and PrivateAssembly2.dll actually use the same library version. This will save you quite a lot of trouble if it is possible.
It is indeed possible to force both versions of Dependency.dll to load into your appdomain by adding a custom resolver that loads it, but be aware that you are entering a rather narrow path if you do this. For instance, there will be different versions of any static variables in both versions, and also the types created in the Folder1\Dependency.dll assembly will not be recognized by the Folder2\Dependency.dll assembly, and vice versa, even though the types might seem to be "the same".
精彩评论