ReflectionTypeLoadException when running dnx (aspnet5)

Today I ran into a problem with starting my AspNet5 app. (for the record, I’m using aspnet version 1.0.0-beta8) This is what happened:

> dnx web
Application startup exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeAssembly.get_DefinedTypes()
   at Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String startupAssemblyName, IList`1 diagnosticMessages)
   at Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureStartup()
   at Microsoft.AspNet.Hosting.Internal.HostingEngine.EnsureApplicationServices()
   at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()
Hosting environment: Production
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

The exception occurs in FindStartupType method, before app is even started. A quick search led me to this SO thread: Run ASPNET5 web application with Kestrel, which suggests there may be a mismatch between current dnx version and downloaded package dependencies. I double checked current dnx version using dnvm list. Then I ran dnu restore to be sure:

> dnu restore
Done, without errors.
Restore complete, 18523ms elapsed

I also tried removing all packages from %UserProfile%\.dnx\packages and restoring them again, but that didn’t help either.

Try to compile then:

> dnu build
Build succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:01.9781471
Total build time elapsed: 00:00:02.0094707
Total projects built: 1

Seems ok to me. What the hell is causing the problem then?

How can I debug this exception, when my code isn’t even running yet? Turns out that dnx has a little option called --debug. Let’s try this:

> dnx --debug web
Process Id: 15396
Waiting for the debugger to attach...

Ok, Let’s attach Visual studio and see what happens. In VS, do Debug -> Attach to Process, then find dnx.exe process and attach to it (if there is more than one, just try to attach to each of them). In the dnx console window you should now see:

Debugger attached.

If the exception is still thrown, and nothing happens in VS, you need to enable breaking on exceptions in VS. Go to Debug -> Windows -> Exception Settings and make sure “Common Language Runtime Exceptions” is checked. (Remember to uncheck it after you’re done with debugging, otherwise debugger will break on all sort of internal exceptions.) Now, repeat the process - restart dnx --debug web and attach VS debugger to it.

And voila, we have our exception caught. What now? How to get details for this exception? Click OK, then open a Watch window (Debug -> Windows -> Watch -> Watch1). In the Name column, type $exception. This is a clever pseudo-variable, which displays information on the last exception. If caught exception is of type ReflectionTypeLoadException, look for LoaderExceptions field and check if there are any understandable exceptions or messages. In fact, you may have already caught the exception which is the real cause of error, even before ReflectionTypeLoadException is thrown.

In my case the problem was:

Exception thrown: 'Microsoft.Dnx.Compilation.CSharp.RoslynCompilationException' in Microsoft.Dnx.Compilation.CSharp.dll

Additional information: c:\projects\dnxtest\dnxtest.core\FilePositionCommand.cs(272,21): DNX,Version=v4.5.1 error CS0162: Unreachable code detected

The compilation error came from a project that my main app was referencing. Why did dnu build succeed then? It seems like dnu doesn’t do full compilation of referenced projects. It checks referenced classes, fields, etc., but it completely ignores any code errors. I’m sure there’s a reason for such behavior, but I think there should be also a way to compile everything, something like dnu build --recursive, or running dnu at the root directory level. Of corse, if you’re using Visual Studio or VS Code, you will see compilation errors. But if you like to stick with commandline and simpler editors - I currently don’t see other way than compiling every project separately. Of course you can write a script that does that, but - shouldn’t something like that be included ‘out of the box’? If the runtime exception was at least a little bit more meaningfull - just RoslynCompilationException instead of cryptic ReflectionTypeLoadException - that would be enough.

I hope that will be fixed in next releases!