0

I am calling a third-party library in two separate programs. One program works and the other does not. The problem is that .NET is attempting to resolve assembly references at different times.

Here are the details. The third-party library has a class initializer that registers a handler for the ResolveAssembly event in the appdomain. If this handler is not registered, a call to the constructor for the class will fail.

In the program that works, this event is raised just before the constructor is called (i.e., in the debugger, I see the event get raised as I step into the constructor). In the program that does not work, the event is raised just prior to the method which contains the call to the constructor (i.e., I see the event get raised as I step into the calling method). In the former case, the event is registered by the class initializer before the event is raised; in the latter, the resolution happens before the class initializer is called, and I later get a "file not found" exception in the constructor.

As the two methods are identical, I have to assume that there is something about the containing program that is causing the different behavior. But I have not been able to identify any compiler options or appdomain settings that might be causing it. Are there any subtle assembly resolution rules that I might be missing?

EDIT: To be clear, I'm asking for a link to information about exactly when the CLR attempts to resolve references, as opposed to how. In both cases, I am calling a method that looks like this:

void CreateObject()
{
     SomeObject o = new SomeObject();
}

In one case, the resolution happens as I step into CreateObject. In the other, it happens just prior to the SomeObject constructor. There has to be a reason why the CLR is able to delay assembly resolution in the second case, but I haven't been able to find it.

DLCross
  • 699
  • 5
  • 13
  • https://stackoverflow.com/questions/1437352/when-is-a-static-constructor-called-in-c – Hans Passant Jun 04 '18 at 22:22
  • @Hans, my question is not about when the static constructor gets called--that's consistent between my two programs. My issue is that the ResolveAssembly event gets raised at different points. – DLCross Jun 04 '18 at 22:24
  • It would be awesome if you could provide a [mcve] for each of the two scenarios you are discussing. – mjwills Jun 04 '18 at 22:30
  • @mjwills, I wish I could. However, the two examples would look identical. That's why I've been fighting this for over a week--I can't figure out what the salient difference is between the two programs. – DLCross Jun 04 '18 at 22:36
  • In the SO question that Hans Passant linked, there's a reference to a Jon Skeet's [book section](http://csharpindepth.com/Articles/General/Beforefieldinit.aspx) which might be worth reading. – Jimi Jun 04 '18 at 22:36
  • `However, the two examples would look identical.` The two programs (one working, one not) are identical? – mjwills Jun 04 '18 at 22:37
  • 1
    "class initializer" is a [java] term, you need to avoid it. It is the Just-in-Time compiler that causes assemblies to be loaded. Just before the first method in a class starts running. Highly unpredictable when that happens because that depends on code execution order and whether you run the Debug or Release build. Use Assembly.Load() to force it to happen earlier. It is pretty common to subscribe AssemblyResolve too late, https://stackoverflow.com/questions/35480817/why-does-assembly-load-seem-to-not-affect-the-current-thread-when-resolving-references-not-through-reflection – Hans Passant Jun 04 '18 at 22:40
  • Thanks, @Hans. It does appear that the resolver is getting registered too late. Unfortunately, it's the third party lib that's doing the registration, so I don't have any control over it. And I'm going to have a tough time explaining to them why they need to change this behavior unless I can find a consistent way to replicate it, other than point to one program where things aren't happening in the expected order. – DLCross Jun 04 '18 at 23:12
  • We can't help you to file that bug report. You've got links to pass on to them to show them how to do it right. – Hans Passant Jun 04 '18 at 23:16

0 Answers0