///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace JetBrains.Build.Omea.Util
{
///
/// Helps with finding the assemblies that are referenced but could not be located by probing.
///
public class AssemblyResolver : MarshalByRefObject, IDisposable
{
#region Data
///
/// .
///
protected readonly AppDomain myAppDomain;
///
/// .
///
protected readonly List myDirectories;
#endregion
#region Init
///
/// Cretaes the resolver and attaches it to the appdomain. Call after use.
///
/// Directories to probe for the missing references.
/// The appdomain we're patching.
public AssemblyResolver(ICollection directories, AppDomain appdomain)
{
if(directories == null)
throw new ArgumentNullException("directories");
if(appdomain == null)
throw new ArgumentNullException("appdomain");
myAppDomain = appdomain;
myDirectories = new List(directories.Count);
foreach(string directory in directories)
{
var di = new DirectoryInfo(directory);
if(!di.Exists)
throw new InvalidOperationException(string.Format("The specified references directory “{0}” does not exist.", di.FullName));
myDirectories.Add(di);
}
myAppDomain.AssemblyResolve += OnAssemblyResolve;
}
#endregion
#region Attributes
///
/// The appdomain we're patching.
///
public AppDomain AppDomain
{
get
{
return myAppDomain;
}
}
#endregion
#region Implementation
///
/// Gets the list of directories for probing.
///
protected List Directories
{
get
{
return myDirectories;
}
}
///
/// Probes for the assembly.
///
protected Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
string sAssemblyShortName = new AssemblyName(args.Name).Name;
foreach(DirectoryInfo di in myDirectories)
{
var fi = new FileInfo(Path.Combine(di.FullName, sAssemblyShortName + ".dll"));
if(fi.Exists)
return Assembly.LoadFrom(fi.FullName);
fi = new FileInfo(Path.Combine(di.FullName, sAssemblyShortName + ".exe"));
if(fi.Exists)
return Assembly.LoadFrom(fi.FullName);
}
return null;
}
#endregion
#region IDisposable Members
///
///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
///2
public void Dispose()
{
myAppDomain.AssemblyResolve -= OnAssemblyResolve;
}
#endregion
}
}