0

Normally referenced assemblies should not be loaded until a specific type from that assembly is used. But here is a the question:

This is a Winforms application. Although the PresentationFramework.dll & System.Xaml.dll assemblies are referenced, they should not be loaded as below code path never executes;

bool useAutoHandler = false;

if (useAutoHandler) // This is always false so below code is not executed!
{
    var currentApplication = typeof(System.Windows.Application).GetProperty("Current");
    if (currentApplication != null)
    {
        var application = currentApplication.GetValue(this, null) as System.Windows.Application;
        if (application != null)
        {
            application.DispatcherUnhandledException += this.DispatcherUnhandledException;
        }
    }
}

When I query loaded assemblies with AppDomain.CurrentDomain.GetAssemblies(), I see presentation framework core & xaml being loaded. Any ideas as to why this is the case?

Teoman Soygul
  • 25,584
  • 6
  • 69
  • 80
  • Well, your code references System.Windows.Application, which I believe is found in PresentationFramework.dll, which references PresentationCore.dll, so I can see both of those assemblies loaded as soon as your code runs. I suspect that a lot is happening before your code runs, some of which is causing the assemblies to load. – John Bledsoe Mar 08 '11 at 19:24
  • System.Windows.Application is from PresentationFramework.dll and MUST be known at compile time, so whatever you do (like 'if') it will always be loaded. If you want load assembly dynamically http://stackoverflow.com/questions/465488/c-load-assemblies-at-runtime – Tomas Voracek Mar 08 '11 at 19:26
  • Yep you are right. Code path doesn't matter, referenced assemblies are loaded regardless of actual usage as long as they are statically referenced. – Teoman Soygul Mar 08 '11 at 19:38

2 Answers2

3

Referenced assembly is loading into the process memory before stepping into method where reference is present.

If you change your code into something like this:

private void Foo()
{
  var currentApplication = typeof(System.Windows.Application).GetProperty("Current");
  if (currentApplication != null)
  {
    var application = currentApplication.GetValue(this, null) as    System.Windows.Application;
    if (application != null)
    {
      application.DispatcherUnhandledException += this.DispatcherUnhandledException;
    }
  }
}

public void Bar(bool useAutoHandler)
{
  if (useAutoHandler)
  {
    Foo();
  }
}

then running Bar(false) should not load extra assemblies.

Alexander
  • 31
  • 1
  • 3
3

You are loading the PresentationFramework.dll assembly in this very same line: typeof(System.Windows.Application) because you are statically referencing a type contained withing this assembly.

If you compile this in Release Mode the compiler would probably optimize this code and completely remove this if from the resulting IL. If the body of the if statement is part of the resulting IL at runtime when the moment for the method containing this code to be executed comes, the JIT will need to translate it into machine code and because you have statically referenced a type within this assembly it would need to load the corresponding assembly.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Well that code never executes since it is enclosed within the block `if (useAutoHandler) { ... }` where useAutoHandler is always false! – Teoman Soygul Mar 08 '11 at 19:18
  • @Teoman Soygul, this doesn't matter. You are statically referencing a class withing this assembly so this assembly needs to be loaded into the AppDomain in order for this code to be successfully JITed. Maybe if you compile in Release mode the compiler would optimize this code and completely remove the body of this `if` and the assembly won't be loaded. – Darin Dimitrov Mar 08 '11 at 19:21
  • Well if this is the case, even though not executed, any code path using any type from an assembly results with assembly getting loaded. I'll test this in a moment. – Teoman Soygul Mar 08 '11 at 19:24
  • 1
    A quick test reveals that this code `if (true == false) { var a = typeof(System.Windows.Application).GetProperties(); }` in an empty console application results in WindowsBase, System.Xaml, PresentationFramework all getting loaded. It turns out it doesn't matter if any type is actually instantiated or used in any execution path. They are loaded regardless. – Teoman Soygul Mar 08 '11 at 19:39