ResolveEventHandler в DLL (библиотека классов)
В C# есть событие ResolveEventHandler для загрузки внешних библиотек DLL, если они не находятся в каталоге приложения.
Чтобы использовать его в приложении winform, я регистрирую событие в функции Program.cs Main() следующим образом:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
а затем есть функция ResolveAssembly, которая вызывается при каждом запуске события:
static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
//MessageBox.Show(String.Format("Assembly {0} is missing", args.Name));
//This handler is called only when the common language runtime tries to bind to the assembly and fails.
//Retrieve the list of referenced assemblies in an array of AssemblyName.
Assembly MyAssembly, objExecutingAssemblies;
string strTempAssmbPath = "";
string AssemblyName = new AssemblyName(args.Name).Name;
objExecutingAssemblies = Assembly.GetExecutingAssembly();
AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
//Loop through the array of referenced assembly names.
foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
{
//Check for the assembly names that have raised the "AssemblyResolve" event.
if (strAssmbName.Name == AssemblyName)
{
//Build the path of the assembly from where it has to be loaded.
strTempAssmbPath = @"C:\PowerVision\libraries\" + AssemblyName + ".dll";
break;
}
}
//Load the assembly from the specified path.
MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
//Return the loaded assembly.
return MyAssembly;
}
Вопрос в том, как я могу добавить / вызвать это событие в / из библиотеки классов?
У меня есть библиотека классов (DLL), которая имеет 3 ссылки на внешние библиотеки DLL. Я не хочу копировать эти библиотеки в каталог приложения и не хочу помещать их в подкаталог приложения. Эти библиотеки DLL должны оставаться в определенной внешней папке (следовательно, с использованием события).
Проблема в том, что я не знаю, где в DLL(библиотека классов) поставить это событие регистрации:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
1 ответ
Вам просто нужно поместить регистрацию событий в вашу DLL в место, которое когда-нибудь будет вызываться, ДО того, как на любую из ваших 3-х внешних DLL будут ссылаться.
Конструктор объекта в вашей верхней DLL будет первым местом для поиска. Однако, если этот объект является подтипом объекта, который находится в одной из этих 3 внешних библиотек DLL, вам может потребоваться создать родительский объект для этого объекта, сначала вызвать родительский объект и добавить регистрацию события в этом объекте. родительский конструктор.
Например, если ваша DLL является UserControl, который основан на другом UserControl, который находится в одной из этих 3 внешних DLL, например:
public partial class TopLevelUserControl: ExternalDllUserControl
{
InitializeComponent();
}
тогда вам может потребоваться написать код, подобный следующему: создайте новый пользовательский элемент управления с именем TopLevelUserControlLauncher и поместите TopLevelUserControl в этот userControl, закрепленный. Затем напишите код так:
public partial class TopLevelUserControlLauncher: UserControl
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
InitializeComponent(); // this will construct TopLevelUserControl
}