Dynamic Loading of .Net Assemblies
Problem: You have dependencies which can be in a number of directories outside of the directory your app is running in. DotNet AppDomains are heavy to say the least and very high in ceremony. You do not want to deal with secondary app domain creation.
Solution: Override AssemblyResolve event on your current app domain.
</p>
public class AppDomainLoader : IAppDomainLoader
{
private ResolveEventHandler _searchAssemblyMethod = _searchDir;
public ResolveEventHandler FindAssemblyMethod
{
set { _searchAssemblyMethod = value; }
}
private static string[] _directoriesToSearch;
private static Assembly _searchDir(Object o, ResolveEventArgs e)
{
foreach (var s in _directoriesToSearch)
{
var filetoload = s + e.Name.Split(‘,’)[0] + “.dll”; //bad one liner that parses the first part of the assembly name and adds .dll at the end
if (File.Exists(filetoload)) //sees if the file is even in the directory
{
return Assembly.LoadFrom(filetoload); //returns assembly once found, a bit naive and does not handle version conflicts well.
}
}
return null;
}
public void Search(string[] directoriesToSearch)
{
_directoriesToSearch = directoriesToSearch; //sets directories to search to allow entry point for dynamic searching
AppDomain.CurrentDomain.AssemblyResolve -= _searchAssemblyMethod; //cleans up previous events, may not be needed.
AppDomain.CurrentDomain.AssemblyResolve += _searchAssemblyMethod; //registered the event
}
}
{
private ResolveEventHandler _searchAssemblyMethod = _searchDir;
public ResolveEventHandler FindAssemblyMethod
{
set { _searchAssemblyMethod = value; }
}
private static string[] _directoriesToSearch;
private static Assembly _searchDir(Object o, ResolveEventArgs e)
{
foreach (var s in _directoriesToSearch)
{
var filetoload = s + e.Name.Split(‘,’)[0] + “.dll”; //bad one liner that parses the first part of the assembly name and adds .dll at the end
if (File.Exists(filetoload)) //sees if the file is even in the directory
{
return Assembly.LoadFrom(filetoload); //returns assembly once found, a bit naive and does not handle version conflicts well.
}
}
return null;
}
public void Search(string[] directoriesToSearch)
{
_directoriesToSearch = directoriesToSearch; //sets directories to search to allow entry point for dynamic searching
AppDomain.CurrentDomain.AssemblyResolve -= _searchAssemblyMethod; //cleans up previous events, may not be needed.
AppDomain.CurrentDomain.AssemblyResolve += _searchAssemblyMethod; //registered the event
}
}
Now whenever there is a missing Assembly, the _searchAssemblyMethod will be fired, and all directories given to the Search method will attempt to find an assembly with the matching name.