Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to load assembly when referencing BindingFlags type in Windows 10 Universal Windows library

When running unit tests, calling any method in my portable runtime library DLL that references the "System.Reflection.TypeExtensions" generates a FileNotFound exception, searching for "System.Reflection.TypeExtensions". The error does not occur when the same code is executed in a Windows 10 Universal app.

The project is a C# portable runtime library, configured to support .net Framework 4.6 and Windows Universal 10.0. The Test project is configured to use .net Framework 4.6.

Whenever I attempt to call a method that uses the System.Reflection.BindingFlags type, I get the following exception. The exception occurs as the call starts (presumably while jit-ing the function).

Test method Sfx.Test.SignalExpressionTest.TestAddExpressions threw exception: 
System.IO.FileNotFoundException: Could not load file or assembly 'System.Reflection.TypeExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.=== Pre-bind state information ===
LOG: DisplayName = System.Reflection.TypeExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 (Fully-specified)
like image 468
Robin Davies Avatar asked Feb 06 '16 20:02

Robin Davies


1 Answers

Adding those packages is the right thing to do. Here is why you see this behavior:

  1. BindingFlags is currently [1] exposed in System.Reflection.TypeExtensions.
  2. When you compile a .NET Core class library, the compiler records the type reference as System.Reflection.TypeExtensions!System.Reflection.BindingFlags.
  3. When you consume the class library from a .NET Framework application, you need to add a reference to System.Reflection.TypeExtensions otherwise the compiler cannot resolve the type. The same is true for a unit testing project which has to deploy all the code in order to run.
  4. At runtime, the CLR will resolve the type, find a type forward that points to mscorlib!System.Reflection.BindingFlags and happily run your code.

As a general rule of thumb: .NET Core is designed to deploy the framework in an app-local fashion, in other words, when your application is deployed to a folder, the closure of all your dependencies need to be deployed too. Although unit test projects are conceptually class libraries, the same applies because they are executed like applications.

Of course, we don't expect folks to manually tweak the references and hunt down dependencies. What you currently see are pre-release bits where not all pieces in our tooling experiences do the right thing.

Two questions from my side:

  1. Which unit testing framework do you use? I assume it's MSTest (Microsoft.VisualStudio.TestTools.UnitTesting), as opposed to xUnit or NUnit?

  2. Which runner are you using? I assume it's the built-in Visual Studio Test Explorer (as opposed to ReSharper or TestDriven.NET)?


[1] I say currently because based on customer feedback we decided to move it back into System.Reflection, together with the APIs that take BindingFlags.

like image 178
Immo Landwerth Avatar answered Oct 24 '22 15:10

Immo Landwerth