здесь
55. Перехват загрузки типов и модулей
Иногда возникает задача перехватить стандартную загрузку модулей и загрузть модуль, лежащий в определенной папке. Например, при решении проблемы локализации приложений, ресурсы могут лежать по папкам с именами языка и в зависимости от выбранного языка нужно загружать соответствующий модуль. Аналогичная задача может возникнуть при поиске модуля, содержащего нужный тип.
Событие AppDomain.CurrentDomain.TypeResolve вызывается, если системе (точнее говоря текущему домену) не удалось найти сборку, содержащую запрошенный тип. Событие AppDomain.CurrentDomain.AssemblyResolve вызывается, если системе не удалось найти запрошенную сборку.
Листинг 23 показывает пример использования этих событий. Главный модуль MainClass использует две сборки: ClassLibrary1, содержащую класс Class1 и ClassLibrary2, содержащую класс Class2. Главный модуль не имеет ссылки на первую сборку, поэтому при попытке найти тип Class1 будет вызываться обработчик TypeResolve, в котором мы загрузим нужную сборку самостоятельно. На вторую сборку ссылка имеется, но у нее выставлен тип CopyLocal=False, поэтому система не сможет определить местонахождение сборки и вызовет обработчик AssemblyResolve, в котором мы загрузим эту сборку самостоятельно.
Листинг 23. Трассировка исключенияОбработка событий AssemblyResolve и TypeResolve
using System;
using System.Reflection;
namespace ResolveAssembly
{
class MainClass
{
static MainClass()
{
AppDomain.CurrentDomain.TypeResolve +=
new ResolveEventHandler(CurrentDomain_TypeResolve);
AppDomain.CurrentDomain.AssemblyResolve +=
new ResolveEventHandler(currentDomain_AssemblyResolve);
}
[STAThread]
static void Main(string[] args)
{
Type t = Type.GetType("ClassLibrary1.Class1", false);
if (t != null)
{
Console.WriteLine(t.Name);
}
else
{
Console.WriteLine("Тип не найден");
}
ClassLibrary2.Class2 c2 = new ClassLibrary2.Class2();
Console.WriteLine(c2.ToString());
}
private static Assembly CurrentDomain_TypeResolve(
object sender, ResolveEventArgs args)
{
Console.WriteLine("Ищу тип: {0}...", args.Name);
if (args.Name.Equals("ClassLibrary1.Class1"))
{
return Assembly.LoadFrom(
@"..\ClassLibrary1\bin\ClassLibrary1.dll");
}
return null;
}
private static Assembly currentDomain_AssemblyResolve(
object sender, ResolveEventArgs args)
{
Console.WriteLine("Ищу сборку {0}...", args.Name);
if (args.Name.IndexOf("ClassLibrary2") >= 0)
{
return Assembly.LoadFrom(
@"..\ClassLibrary2\bin\ClassLibrary2.dll");
}
return null;
}
}
}