Resolving .NET assembly name collision - c#

I currently have a .NET application which references "SomePackage.dll" and "SomeUtilities.dll".
SomePackage.dll is contained in a separate folder, and one of the assemblies it depends on is also named "SomeUtilities.dll".
In other words, I added a reference in my project to \somePath\SomePackage.dll, and there exists a file \somePath\SomeUtilities.dll that SomePackage.dll depends on. Since I already have a reference in my project to a assembly called SomeUtilties.dll, I could not add a reference to \somePath\SomeUtilties.dll.
As a result, when I try to run my application and initialize a module in from SomePackage.dll, I receive an error:
Could not load file or assembly 'SomeUtilities.dll..." or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.'
To work around this, I used gacutil in the VS developer command prompt to add \somePath\SomeUtilities.dll to the GAC. Now both assemblies are resolved fine, but I was wondering if there was a better way to resolve this name collision that doesn't involve adding to the GAC. I'm worried about potential issues that may arise with installing into the GAC, and have heard that .NET has the ability to look through certain subfolders to resolve assemblies, but am not sure where to find more on this concept.

You can use bind redirect.
Open the .config file to find the location of < assemblyBinding>
Remove the < assemblyBinding> reference.
Type in Package Manager Console: Add-BindingRedirect.

Windows/.NET has a tool called FUSLOGVW.exe that will help find issues with assemblies. This tool is useful but sifting through the logs is cumbersome. There is an open source tool that is a wrapper around FUSLOGVW.exe and makes it much easier to sift through the data and find the root of the problem. I would use this
https://github.com/awaescher/Fusion

Related

Why do this occurs "Could not load file or assembly.." in C# class Library

I'm newbie to .net projects. Although I was able to code in c# & use it's frameworks, Some times I face exceptions which I really didn't get any proper resource/suggestion to modify or rectify them. Hope I would get clear this time.
The exception which I faced is as follows :
Could not load file or assembly 'Microsoft.AspNetCore.Cryptography.KeyDerivation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.
I'm really confused with such type of exceptions. What's the reason for those & how we needs to cross check to clear those ?
Here is what I did install: "Microsoft.AspNetCore.Cryptography.KeyDerivation" from nuget console with version 2.2.0.
My installed packages list image :
The main reason for this type of error is a result of your output folder. Take a look at where your binary outputs were placed. Inside of that folder (usually your .exe or .dll output, not sure what kind of .NET project you're writing), you should also have all of your dependency dlls. In this case, the dll related to Microsoft.AspNetCore.Cryptography.KeyDerivation is missing. So when you go to run your executable, it complains "Could not load file or assembly KeyDerivation" because it couldn't find it.
To resolve this issue, double check your project's references and that there are no issues with the Microsoft.AspNetcore.Cryptography.KeyDerivation reference (what I mean is, make sure there are no yellow exclamations or other icons showing up next to this reference in your Solution Explorer). If you have any issues, remove the reference, then add the nuget package again.

How to force visual studio to check for broken file references at compile time

This question is specifically about file references
My project has a reference to library A. Library A has a reference to library B.
If I don't add a direct reference to library B, the project will compile fine, but then throw a "could not load file or assembly B" exception at runtime when it tries to load library A.
So, how do I force visual studio to check for all broken file references at compile time? Alternatively, is there any other way to find these broken references (a tool, VS extension, etc.)
Here's an example project that reproduces the behavior.
https://github.com/RaikolAmaro/BrokenDependencies
This isn't a compile-time problem, as, at compile time, all required references were present and accounted for. Otherwise, it wouldn't have compiled in the first place.
It's a runtime problem and Visual Studio doesn't care much about what you want to have in the output directory or not. This is why you have total control over which elements you want copied from NuGet packages as well as other projects. Why? Because you may be using a installer or packaging solution or have some magic assembly resolving code to find your dependencies. You may be relying on plugins or configuration based dependency injection. Too many things which will thwart a scan like this.
There is another problem. While an assembly may depend on a certain other assembly, your code may not require it. It that's she case, if your code never loads a codepath that requires this other assembly, then you don't need it in your output directory to run.
There are tools that scan all the codepaths in your projects, the assemblies they depend on and so forth. These can be used to see whether you have all the required binaries to run the code.
http://www.dependencywalker.com/
There is problem with these tools. The same problems mentioned above. If you use dependency injection through configuration or convention (e.g. based on reflection) or do your own reflection, or depend on the dynamic keyword, then these tools may not be able to find all codepaths you depend on and may require some configuration or in-source annotation to figure that out while scanning.

What causes Microsoft.Practices.Unity assembly not to load?

I am running a project that had been running without issue for some time but recently started throwing an error stating,
"Could not load file or assembly 'Microsoft.Practices.Unity,
Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
or one of its dependencies. The system cannot find the file
specified."
I see that this assembly is for IoC/Dependency Injection support however I never explicitly added it to the solution; although I do see that it is in fact there.
When I check the version of the assembly it is showing the same version that is being referenced in the above error; so I cannot figure out why the file cannot be found by the project.
In effort of resolving the issue I've cleaned the solution, deleted my obj folder, rebuilt, removed and even reinstalled the assembly via nuget but the issue persists.
I've found somewhat similar issues reported here on SO but the proposed resolutions were either not applicable because it was not the same assembly reference as the one I'm having issue with OR it involved configuration of a XAML based application. This is ASP.NET.
The only other clue that I could find as to why I'm having the problem is that the targeted runtime framework of the assembly is v2.0.50727 and this application is .NET 4.5
Which would seem a reasonable explanation for the problem from my limited perspective except that the app was previously running without the problem.
I'd also mention that the assembly isn't explicitly being called from the block of code throwing the error; which is simply creating a web service client and calling a method.
long memberId = 1326728123;
ServiceClient sc = new ServiceClient("ServiceClientEndPoint");
var leadPackage = smc.GetLeadPackages(memberId);
So there could be other variables of this equation that may be attributing to the problem (e.g. Network blocking and etc)
I just wanted to make certain that I may not be missing something by running it past SO before wasting time going in the wrong direction for an answer.
Note that this could mean a number of things, including that one of the dependent assemblies of Microsoft.Practices.Unity could be loaded.
The first place searched is the GAC, if you are building and running on the same machine, this probably won't cause a problem because the runtime will also find the same library but if you are deploying, the project will sometimes bind to the GAC library whereas the production server might not have it installed and it will fail to run. CopyLocal=true should fix that but if you are deploying, you should check that the library is copied into the bin directory.
Secondly, you should open Microsoft.Practices.Unity.dll using reflector or ilspy.exe and see what other dependencies it has (other than the System.* libraries) since any other ones will need the same treatment as Microsoft.Practices.Unity i.e. adding to the project and copy local set to true.

Could not load type 'myinterface' from assembly

I have a solution that includes several projects. A few are libs that are building dll's used in my main project in this solution.
My main project builds with output type console application.
This all works fine.
When i change the build output type to a class library (since i want to use this project as a plugin eventually). The project will still build, this time to a dll.
When i use this plugin in an application where i use it as a dll however, it will run up to a certain point where it's trying to load a type defined in an external dll (so NOT built by my solution) and throw the exception:
Could not load type 'externalinterface' from assembly 'externallib, version=3.0.0.0, Culture=neutral, PublicKeyToken=null'.
The dll's are all in the correct folder,etc.
Also worth noting, the plugin is tested in another location than where i built it. The executable still works on this location, the dll/plugin does not. Same amount of dll's in their folders etc.
EDIT: I already used ILSpy (dll inspector) to open the actual dll that is being referenced (so externallib in the errormessage) and checked if 'externalinterface' was present and it is.
EDIT2: RESOLVED! The program that loaded my plugin was loading the same dll that caused the exception. The dll it loaded was of another version than the one i loaded.
Check whether the type externalinterface is present in the referred dll.
You didn't include the details of the exception the application is throwing. However, based on the message you gave, it appears your assembly does not have a strong name. If the application attempting to load your assembly as a plugin does have a strong name, then .NET will require all assemblies loaded by it also have a strong name, so you need to configure your assembly to have a strong name before continuing.
Maybe some supported dll's which is used by the 'externalinterface' is missing in the target machine. In the target machine, check is all the necessary dll's are present in the output folder.
Or blindly copy paste all the dlls in the output folder from the machine where the code is working to the target machine where you have the problem. After this, if the code is working in the target machine, then try to analyze which supporting dll you are missed to copy.

.NET Load assemblies at runtime Again

I posted a similar question a time ago. I need to load an assembly at runtime.
This is easy if I know the absolute path of the dll at runtime.
But I dont :( The assembly.Load() or LoadFromFile() fails if the file is not in the application root.
The only thing I have is the dll name. The dll could be located in the root, system32 or in even in the GAC.
Is it possible for .net to automatically determine where the dll is at, like for example :
it should first look in the root. If its not there move on to the system folders, else try the GAC.
EDITED
I am using plug-in architecture. I do not need to register the dll. I have a multi user application. I have a applications table containing information regarding applications. Each application has a dll path associated with it, containing certain algorithms associated with that app. Hope this helps.
I hope you've read up on the following. My suggestion...
How the runtime locates assemblies
You can give Assembly.LoadWithPartialName a whirl.. might work.. it says it will search the application folder and the GAC unlike Assembly.Load. (However its less safe.. coz you might end up with the wrong version of the DLL since you dont specify all 4 parts of the Assembly Name)
Also try AppDomainSetup.PrivateBinPath (AppDomain.AppendPrivatePath has been deprecated in favor of this) to add subfolders of the application root to the list of folders to probe assemblies for. You can also try copying over files from other places into a [AppFolder]\MySandboxForDLLsToLoad, which is added to the PrivateBinPath.
When the current application looks for assemblies, it looks in several locations (bin folder, gac, etc..) if it can not find one, then the developer needs to manually tell the application where to look. You can do this by intercepting the AssemblyResolve event, and using the event args to tell the CLR where your assembly is.
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
....................
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var strTempAssmbPath=
Path.GetFullPath("C:\\Windows\\System32\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
var strTempAssmbPath2=
Path.GetFullPath("C:\\Windows\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
if (File.Exists(strTempAssmbPath))
return Assembly.LoadFrom(strTempAssmbPath);
if (File.Exists(strTempAssmbPath2))
return Assembly.LoadFrom(strTempAssmbPath2);
}
You can hook up into AppDomain.CurrentDomain.AssemblyResolve event and load the assembly for your application manually on demand.
Yes there is a way and it depends on whether your dll is weakly(without a public key token) or strongly(with a public key token) named. If its weakly named and you have added a reference to the assembly with the dll within VS, then VS will first look in the application folder root and if it does not find it, it will then look in the subdirectories that you specify as the value of the privatePath attribute in your XML config file.
If its a strongly named dll, then the CLR will search in the GAC so you need to install the dll in the GAC. The CLR can also look in the application directory if you install an XML config file that has its codeBase element pointing to the dll's path.
To specify an assembly in the GAC you can use the /reference:[DLL name] switch when compiling your assembly.
The dll will be found automatically is it is in some location referenced in the PATH system variable (i.e., system32) or if the dll is registered. You can't find it if it can be anywhere on disk, but no one needs that functionality anyway.
EDIT: can the dll's be registered? how are you getting the assembly name if you don't know of the assembly ahead of time? Are you creating some type of plug-in architecture? I think it would help if you explained your situation a bit more.
EDIT2: If that is the case, why not provide a way for the user to register his or her plug in? You can get all the information that you need from an open file dialog. That or simply make them dump it into a folder that you specify.
You have three options
Install the assembly in the global assembly cache (GAC)
Use an application configuration (.config) file with the tags
Use the AssemblyResolve event
You can find the details here.
The resolution algorithm used by .NET to find the assemblies and their dependents is straight forward.
.NET identifies the required version. Usually the information about the dependant assemblies is present in the application's assembly manifest.
.NET searches GAC (Global Assembly Cache), only if the assembly is strong named.
If not found in GAC, and if a .config file presnt, then .NET searches the location specified in the cofiguration file, else .NET searches directory containing the executable (.EXE)
After this, If the assembly is still not found, the application terminates with error.
Click here for the video explaining the .net resolution algorithm, and click here for a video on late binding assemblies
Register this assembly into the GAC. How to do that
Use this
Assembly.LoadWithPartialName(assemblyName);

Categories