1

I am trying to use AssemblyResolve to resolve dependencies for AnyCPU platform.

I have 3 classes:

class Resolver {
    public static void Startup() { }
    static Resolver()
    {
          AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs 
        ...
    }
}

class Foo {
    private ClassFromAssembly _foo;

    public Foo() {
        _foo = new ClassFromAssembly();
    } 
}

class Bar {
    static Bar() {
        Resolver.Setup();
    }

    public voidFoo() {
        var foo = new Foo();
        //...
    } 
}

I am trying to load the ClassFromAssembly class with the AssemblyResolve event. But it seems that AssemblyResolve never fired.

I have two DLLs that contains the ClassFromAssembly one is for x86 and one for x64. I want to dynamically load them when I am on AnyCPU platform, but AssemblyResolve never fired.

Why AssemblyResolve dose not fire?

nrofis
  • 8,975
  • 14
  • 58
  • 113
  • Possibly, because you reference `Foo` from `Bar`, the assembly is resolved before you get to execute `Resolver.Setup`. Look at the output window in Visual Studio when running in debug to know exactly at what moment the assembly is loaded – Kevin Gosse Apr 30 '17 at 13:30
  • It seems that the DLL loaded **after** I set the event `AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;` – nrofis Apr 30 '17 at 13:38

1 Answers1

1

The behavior you see is caused by method inlining that might be performed by .NET runtime.

To make your scenario work, please ensure that affected method is not inlined. Like so:

class Bar {
    static Bar() {
        Resolver.Setup();
    }

    public voidFoo() {
        _DoTheJob();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    void _DoTheJob() {
        var foo = new Foo();
        //...
    }
}

Once method is not inlined, it is guaranteed that your resolver will be installed first, and the assembly containing ClassFromAssembly will be loaded after the resolver is installed.

P.S. Also ensure that assembly of interest is not loaded before you install the assembly resolver. Otherwise, the missed assembly references won't be resolved and those failures will be cached in current AppDomain forever, e.g. you will never get AssemblyResolve event for them again.

ogggre
  • 2,204
  • 1
  • 23
  • 19
  • It seems that the DLL loaded after I set the event `AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;` Your solution didn't worked for me... – nrofis Apr 30 '17 at 13:59
  • @nrofis Subscribe to `AssemblyLoad` event to be absolutely sure when the assembly of interest is loaded. This will give you the right hints. – ogggre Apr 30 '17 at 14:01
  • @nrofis Please also note that `AssemblyResolve` event is only raised when the assembly of interest cannot be located by the usual resolution process. For example, if the assembly is laying around near your .EXE, you won't get `AssemblyResolve` event. Try do delete it and only then `AssemblyResolve` is going to work. – ogggre Apr 30 '17 at 14:07
  • Just did, `AssemblyLoad` of interest DLL called **after** I register to `AssemblyResolve` – nrofis Apr 30 '17 at 14:07
  • But the DLL is in the references... VS copy it automatically near to the EXE file... – nrofis Apr 30 '17 at 14:08
  • @nrofis Select the reference in VS Solution Explorer, press F4 (this will show Properties window), and set `Copy to Output Folder` to `false` – ogggre Apr 30 '17 at 14:10
  • Thanks!! it was the problem – nrofis Apr 30 '17 at 14:12