using System;
using System.Collections.Generic;
using System.Text;
namespace RDNZLUtil
{
///
/// An utility class with static methods for RDNZL.
///
public class RDNZLUtil
{
}
///
/// The ResolverHelper class can be used to add additional
/// paths to search for assemblies in the Load context. It uses
/// the AppDomains AssemblyResolveEvent, which is not recommended
/// by Microsoft.
///
/// In theory, this could be done inside RDNZL, but at least for ACL7
/// (2007-04-26) the application crashes when returning the freshly
/// loaded assembly to the AppDomain that fired the event.
///
/// An additional trick would here be to not use LoadFile, but instead
/// load the raw bytes of the assembly and use mydomain.Load(bytes) instead.
/// This avoids having the file locked by the runtime.
///
///
///
public class ResolverHelper
{
private ResolveEventHandler resolver;
private AppDomain mydomain;
///
/// The list of additional paths to search for a given assembly.
///
public List AdditionalPaths = new List();
///
/// Add a directory path to the list of AdditionalPaths in which to search for assemblies
///
/// A directory path
public void add_AdditionalPaths(String newpath)
{
if (System.IO.Directory.Exists(newpath))
AdditionalPaths.Add(newpath);
else throw new System.IO.DirectoryNotFoundException("Can't add non-existing directory to the ResolverHelper: " + newpath);
}
///
/// Remove a directory path from the list of AdditionalPaths in which to search for assemblies
///
/// A directory path
public void remove_AdditionalPaths(String boguspath)
{
AdditionalPaths.Remove(boguspath);
}
///
/// Create a ResolverHelper and add its resolver delegate to the AppDomains AssemblyResolveEvent.
///
/// An application domain
public ResolverHelper(AppDomain domain)
{
mydomain = domain;
resolver = new ResolveEventHandler(this.Resolver);
}
///
/// Empty constructor adds a ResolverHelper to the current AppDomains AssemblyResolveEvent.
///
public ResolverHelper()
: this(AppDomain.CurrentDomain)
{
}
///
/// Start using this ResolverHelper to resolve assemblies
///
public void Activate()
{
mydomain.AssemblyResolve += resolver;
}
///
/// Stop using this ResolverHelper to resolve assemblies
///
public void Deactivate()
{
mydomain.AssemblyResolve -= resolver;
}
///
/// This is the function that will actually try to find a missed assembly in the
/// additional paths.
///
/// Normally an AppDomain
/// Event args from the failed search, basically the assembly name
///
private System.Reflection.Assembly Resolver(Object Sender, System.ResolveEventArgs args)
{
String assemblyName = args.Name;
String fullName = assemblyName + ".dll";
foreach (string path in AdditionalPaths)
{
String fullPath = path + fullName;
if (System.IO.File.Exists(fullPath))
{
return System.Reflection.Assembly.LoadFile(fullPath);
}
}
return null;
}
}
}