Scenario: We have a solution that depends on different versions of a non-redistributable dll, so until now we have created building rules that we use when we want to build against this dll. We have a folder per dll  and we have to pick the correct one for the environment that we want to setup. Question: Can we figure out what is the correct version of the dll installed in the environment and load it programmatically? Yes, we can do that! It’s a solution that isn’t pretty but it gets the job done!

  • First of all, we’ve to declare explicitly what are the assemblies we support for the solution

[code lang=”csharp”]supportedDlls = new Dictionary();
supportedDlls.Add(
“Microsoft.TeamFoundation.Client”,
new string[]{
“Microsoft.TeamFoundation.Client, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”,
“Microsoft.TeamFoundation.Client, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”,
“Microsoft.TeamFoundation.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”}
);
[/code]

  • In the code where the dlls are used we subscribe to the event that is raised when an assembly cannot be found or loaded.

[code lang=”csharp”]AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;[/code]

  • In the handler we try to load another instance of the assembly supported and if it fails we try with the other.

Note: in the handler we first have to unsubscribe from the event to prevent a loop and after try to load the dll subscribe again.

[code lang=”csharp”]AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
Assembly assembly = resolveSupportedAssembly(supportedDlls[args.Name.Split(‘,’).First()]);
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
return assembly;

static Assembly resolveSupportedAssembly(string[] versions)
{
Assembly assembly = null;
foreach (string version in versions){
try {
assembly = Assembly.Load(version);
return assembly;
}
catch{}
}
return assembly;
}
[/code]

Recap: So if the environment where you want to run the application has the same version of the dll that the solution compiled has it will work without needing to do anything else. In the case that the environment has another version of the dll installed (e.g a major version) , when the application runs, it will make use of the loop in the code trying to load the correct dll by itself.

Here is the link to the repository with this sample code: https://github.com/lremedi/ResolveDlls

Join the Discussion

    There are currently no comments.

    + 43 = 45