2012-06-20 7 views
3

Мне нужно подключить событие AssemblyResolve на моем созданном AppDomain, когда я установил DisallowApplicationBaseProbing = true. Причина, по которой я делаю это, - заставить среду выполнения вызвать событие AssemblyResolve, необходимое для разрешения сборки, вместо того, чтобы сначала опробовать. Таким образом, другой разработчик не может просто вставить MyDllName.dll в каталог ApplicationBase и переопределить сборку, которую я хотел загрузить в событии AssemblyResolve.Необходимо подключить событие AssemblyResolve, когда DisallowApplicationBaseProbing = true

Проблема с выполнением этого заключается в следующем ...

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, он не знает, где найти эту сборку. У меня есть курица & проблема с яйцом кажется. Он должен разрешить мою сборку, чтобы подключить сборщик, но для решения моей сборки нужен сборщик.

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

-Mike

+0

Вы видите вывод 'Console.WriteLine (« Hello »);'? Если да, возможно, вам следует реализовать логику, способную разрешать сборки. Я наткнулся на этот вопрос, потому что у меня такая же проблема. Если я найду решение, я отправлю ответ. –

ответ

4

С большим количеством экспериментов, которые я получил следующую работу:

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); 

К сожалению, я не могу разделить код для разрешения и загрузки сборок. Во-первых, он пока не работает. Во-вторых, в этом контексте будет слишком много и слишком конкретным, чтобы поделиться с широкой публикой.

Я буду загружать структуру объекта, которая сериализуется вместе с сборками, необходимыми для десериализации из одного файла. Для этого я действительно заслуживаю прямо к адду.