[Mono-dev] Assemblies in the CLR system directory and F# scripting.

Matthias Dittrich matthi.d at googlemail.com
Thu Apr 16 10:08:54 UTC 2015

Hi all,

TL;DR: We should remove System.Web.Razor.dll, EntityFramework.dll (and
possibly more) from "/usr/lib/mono/4.5"

I noticed that some assemblies (namely "EntityFramework" and
"System.Web.Razor" and possibly more) lead to problems when used within
a F# script file. The problem is the following:

Assume you use NuGet to download the latest Razor-3 package and then do
the following (in an F# script file):

#I "packages/Microsoft.AspNet.Razor/lib/net45"
#r "System.Web.Razor.dll"

Note that this is the usual way of loading assemblies in F# scripting
and it works fine on Windows/.NET.

However because this is the same as using
/reference:System.Web.Razor.dll" on the C# compiler and because mono has
a "System.Web.Razor.dll" in its CLR system directory (/usr/lib/mono/4.5)
it will redirect the reference (CLR system directory is always
preferred, see https://msdn.microsoft.com/en-us/library/s5bac5fx.aspx).

This already hit me several times:
 - https://github.com/fsharp/FSharp.Compiler.Service/issues/313
 - https://github.com/tpetricek/FSharp.Formatting/pull/279

I'm not really sure why mono actually needs those file to live there.
For referencing the NuGet package should be fine. To load the correct
(mono compatible) version on runtime the GAC should do it.
IMHO we can just remove the System.Web.Razor.dll (and possibly others?)
from the runtime directory.
@akoeplinger noted the following in the gitter chat: It would be a
breaking change for people depending on "/reference:System.Web.Razor" to
just work.
But I'm not sure how common that is with the NuGet package in place.
IIRC xbuild and msbuild always use fully qualified references, so it
shouldn't be a problem for them.

So... Is removing those file something we can do? I just wanted to bring
attention to this issue as it can be *really* hard to debug. The
workarounds in place for this are required anyway to work with older
mono versions. The workaround in itself is simple you just need to use
the fully qualified reference instead:

#r "packages/Microsoft.AspNet.Razor/lib/net45/System.Web.Razor.dll"

However this can be a problem if you don't know in advance in which of
the included directories ("#I") the file is living. (Because F# will
stop executing if the fully qualified reference doesn't exists).


More information about the Mono-devel-list mailing list