Необходимо подключить событие AssemblyResolve, когда DisallowApplicationBaseProbing = true
Мне нужно подключить событие AssemblyResolve к моему созданному домену приложений, когда я установил DisallowApplicationBaseProbing = true. Причина, по которой я это делаю, состоит в том, чтобы заставить среду выполнения вызывать событие AssemblyResolve, необходимое для разрешения сборки, вместо того, чтобы сначала проверять. Таким образом, другой разработчик не может просто вставить MyDllName.dll в каталог ApplicationBase и переопределить сборку, которую я хотел загрузить, в событии AssemblyResolve.
Проблема с этим заключается в следующем...
class Program
{
static void Main()
{
AppDomainSetup ads = new AppDomainSetup();
ads.DisallowApplicationBaseProbing = true;
AppDomain appDomain = AppDomain.CreateDomain("SomeDomain", null, ads);
appDomain.AssemblyResolve += OnAssemblyResolve;
appDomain.DoCallBack(target);
}
static System.Reflection.Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
Console.WriteLine("Hello");
return null;
}
private static void target()
{
Console.WriteLine(AppDomain.CurrentDomain);
}
}
Код никогда не проходит через строку += OnAssemblyResolve.
Когда код пытается выполнить, новый домен приложения пытается разрешить сборку, в которой я выполняю. Поскольку DisallowApplicationBaseProbing = true, он не знает, где найти эту сборку. Кажется, у меня проблема с курицей и яйцом. Он должен разрешить мою сборку, чтобы подключить распознаватель сборки, но нужен разрешатель сборки, чтобы разрешить мою сборку.
Спасибо за любую помощь.
-Майк
1 ответ
С большим количеством экспериментов я получил следующую работу:
internal class AssemblyResolver : MarshalByRefObject
{
static internal void Register(AppDomain domain)
{
AssemblyResolver resolver =
domain.CreateInstanceFromAndUnwrap(
Assembly.GetExecutingAssembly().Location,
typeof(AssemblyResolver).FullName) as AssemblyResolver;
resolver.RegisterDomain(domain);
}
private void RegisterDomain(AppDomain domain)
{
domain.AssemblyResolve += ResolveAssembly;
domain.AssemblyLoad += LoadAssembly;
}
private Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
// implement assembly resolving here
return null;
}
private void LoadAssembly(object sender, AssemblyLoadEventArgs args)
{
// implement assembly loading here
}
}
Домен создается так:
AppDomainSetup setupInfo = AppDomain.CurrentDomain.SetupInformation;
setupInfo.DisallowApplicationBaseProbing = true;
domain = AppDomain.CreateDomain("Domain name. ", null, setupInfo);
AssemblyResolver.Register(domain);
Извините, я не могу поделиться кодом для разрешения и загрузки сборок. Во-первых, это пока не работает. Во-вторых, это будет слишком много и слишком конкретно, чтобы поделиться с широкой общественностью в этом контексте.
Я начну загружать объектную структуру, которая сериализуется вместе со сборками, необходимыми для десериализации из одного файла. Для этого я действительно заслуживаю прямого перехода в.dll ад.