Вопрос по clr, appdomain, appdomainsetup, c# – Загрузка сборок с зависимостями в другой домен приложения

3

Моя цель - выполнить проверку отсутствующих зависимостей между двумя заданными папками. Представьте себе следующую настройку.

Root \ Dira \ A.DLL

Root \ DIRB \ B.dll

B зависит от A.

Поэтому, учитывая эти папки, я хочу создать новый AppDomain, загрузить B.dll и автоматически разрешить и изолировать зависимость от DirA (A.dll) в этом новом AppDomain.

Изоляция является ключевой здесь, учитывая, что когда я выгружаю этот домен приложений, я хочу создать новый с потенциально DirA в качестве зависимости снова, но библиотекам DirC, которые этого требуют, так что в случае, если DirC также имеет зависимость от DirB, я хочу, чтобы он выбрасывал исключение.

Изменить: добавление примера кода на случай, если это поможет лучше описать мой вопрос.

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = @"C:\Root";
setup.ApplicationName = "Isolated Domain"
setup.PrivateBinPath = @"DirA;DirB";
setup.PrivateBinPathProbe = "";//disable search in AppBase..
var domain = AppDomain.CreateDomain(Guid.NewGuid().ToString(),
                                    AppDomain.CurrentDomain.Evidence,
                                    setup,
                                    AppDomain.CurrentDomain.PermissionSet);
//The following statement in theory should pick B.dll's dependency from DirA.
var assembly = domain.Load(AssemblyName.GetAssemblyName(@"C:\Root\DirB\B.dll").Name);
//Do the same in a different domain for C.dll

Спасибо за любую помощь в этом.

Ваш Ответ

2   ответа
3

ResolveEventHandler (подробнее оMSDN относительно разрешения неизвестных сборок)

Итак, вы можете написать что-то вроде

class MyResolver
{
  public static Assembly MyResolveEventHandler( Object sender, ResolveEventArgs args )
  {
    // confirm args.Name contains A.dll
    String dllName = args.Name.Split({','}, SplitStringOptions.None)[0];
    if (dllName == "A")
    {
      return Assembly.LoadFile(@"C:\Root\DirA\A.dll")
    }
    return null;
  }
}

и в созданном вами домене вы сделаете:

domain.AssemblyResolve += new ResolveEventHandler(MyResolver.MyResolveEventHandler);

Убедитесь, что вы связали событие, прежде чем ссылаться на A в B.

Если вы установили setup.DisallowApplicationBaseProbing = true; вновь созданный домен получает событие AssemblyResolve, в противном случае родительский домен получает его
Да, я знаю об этом событии, но не могу получить реализацию, которая использует его для работы :( Konstantinos
Спасибо, я дам вам знать, если это сработает, как только у меня будет шанс попробовать. Konstantinos
@ShaunO: Ваш комментарий спас меня! Будущие искатели: читайте это!
Добавление комментария для будущих поисковиков - событие AssemblyResolve должно обрабатываться наparent AppDomain, а не дочерний AppDomain. Дочерний AppDomain будет запускать событие на родительском AppDomain при возникновении ошибки при разрешении сборки.
1

следовать GAC и PrivateBinPath глубже в папку, но они не могут исследовать другие папки.

Идея состоит в том, что базовый путь AppDomain будет корневой папкой в приведенном выше примере. Konstantinos

Похожие вопросы