Where is System.Object?

Posted on January 9, 2015 in umbraco , dotnet

Our Umbraco Zbu.ModelsBuilder tool relies on Microsoft Roslyn project to parse and analyze existing C# code, and to compile the models DLL. At one point when creating the models builder, everything was working fine except for all Razor views, that failed to compile with the following error:

The type 'System.Object' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System.Runtime, Version=4.0.0.0'

There is an easy fix (see at the end of this post) which I applied at the time, and everything was back to normal. Still, the root question remains: how can System.Object not be defined when the CLR is running?

Where's System.Object?

Roslyn includes Microsoft.CodeAnalysis.CSharp, which depends on two libraries, System.Collections.Immutable and System.Reflection.Metadata. Both are Portable Class Libraries, ie managed assemblies that target more than one .NET Framework platform. As such, they reference System.Runtime, which defines some of the basic types (eg System.Object or System.String) for the Portable environment.

If you explore one of those libraries with a tool such as dotPeek, you can see that they reference System.Runtime, at eg C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETPortable\v4.5\Profile\Profile259\System.Runtime.dll.

That DLL does contain System.Object, System.String, etc. and is used when running in the Portable environment. On the other hand, the desktop framework has its own version of that DLL at eg C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll. That DLL is empty; indeed, on the desktop environment, these basic types live in mscorlib.

The problem

Still, System.Runtime is referenced, and the compiler looks for that reference when checking the types for the portable libraries—the first one being System.Object.

However, as explained in this StackOverflow post, the runtime enviromnent of an ASP.NET/MVC project fails to properly infer all the references required in order to compile views.

So... System.Runtime is not referenced, hence the error message.

The fix

In order to fix this, for as long as the runtime environment is not fixed, you need to explicitely tell the compiler to reference System.Runtime with the following lines in web.config:

<compilation debug="true" targetFramework="4.5">
  <assemblies>     
    <add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />   
  </assemblies>
</compilation>

This will make the compiler happy—even though System.Object was always there, of course, in mscorlib.

There used to be Disqus-powered comments here. They got very little engagement, and I am not a big fan of Disqus. So, comments are gone. If you want to discuss this article, your best bet is to ping me on Mastodon.