Roslyn: Need a way to specify binding redirects in C# Interactive

Created on 2 Dec 2015  路  10Comments  路  Source: dotnet/roslyn

I'm facing this issue in C# Interactive, as bundled with VS 2015 Update 1.

When trying to load FsPickler.CSharp from C# Interactive:

#r "../../packages/FSharp.Core/lib/net40/FSharp.Core.dll"
#r "../../packages/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
#r "../../packages/FsPickler/lib/net45/FsPickler.dll"
#r "../../packages/FsPickler.Json/lib/net45/FsPickler.Json.dll"
#r "../../packages/FsPickler.CSharp/lib/net45/FsPickler.CSharp.dll"

var serializer = Nessos.CsPickler.CsPickler.CreateJsonSerializer();

I get the following error:

System.IO.FileNotFoundException: Could not load file or assembly 'FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at Nessos.CsPickler.JsonSerializer.Create(Boolean indent, Boolean omitHeader)
   at Nessos.CsPickler.CsPickler.CreateJsonSerializer(Boolean indent, Boolean omitHeader)
   at Submission#0.<<Initialize>>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

This happens because I'm referencing FSharp.Core 4.4.0.0, whereas FsPickler.CSharp has been compiled against FSharp.Core 4.3.0.0. I can make the problem go away by either

  1. Stop using FSharp.Core 4.4 and roll back to 4.3 or
  2. Add an explicit binding redirect to FSharp.Core 4.4 in InteractiveHost.exe.config at the Visual Studio installation folder.

The problem is that solution (1) might be impossible depending on what type of dependencies I need to load for my session and solution (2) is simply wrong, enforcing a redirect policy that really depends on the type of application I'm working on in the current session.

So I was wondering whether there might be an easier way to dynamically specify binding redirects from a user perspective. Coming from an F# background, my expectation was that adding an explicit reference to an FSharp.Core at the top of my script would also introduce an implicit binding redirect to that particular assembly version. Thoughts?

Area-Interactive Feature Request Interactive-ScriptingLogic

Most helpful comment

This is still happening, any news on when/if it's going to be fixed?
As others have said, for big projects where you want to try stuff fast C# interactive becomes useless.

All 10 comments

I think Interactive should have a simplified binding model like that of CoreCLR, Silverlight, etc. If an explicit version has been referenced, automatically resolve lower versions up to it.

@tmat Thought we talked about doing this? Or was this just in the compiler?

@davkean is there an easy way to somehow define binding redirects with the current release?

@amcasey @KevinH-MS ?

I'm not aware of a way to specify binding redirects, but I know @tmat has work in flight in this area.

I did some further experiments, this time attempting to explicitly add any binding redirects to InteractiveHost.exe.config . I still couldn't get it to work, this time getting a somewhat different error:

System.TypeInitializationException: The type initializer for 'MBrace.Azure.AzureWorker' threw an exception. ---> System.TypeInitializationException: The type initializer for '<StartupCode$MBrace-Azure>.$Client' threw an exception. ---> System.IO.FileLoadException: Could not load file or assembly 'FsPickler, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) ---> Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoaderException: Assembly 'FsPickler' has already been loaded from 'C:\Users\eirik\AppData\Local\Temp\InteractiveHostShadow\76d148d6-a022-4a9e-ba87-45f7590fa458\f9809339-a0cd-4b6b-99ea-0d82e8e67549\FsPickler.dll'. A different assembly with the same name can't be loaded unless it's signed: 'C:\Users\eirik\Development\mbrace\MBrace.Azure\bin\FsPickler.dll'.
   at Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader.ResolveAssembly(AssemblyIdentity identity, String loadDirectoryOpt)
   at Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader.ResolveAssembly(String assemblyDisplayName, Assembly requestingAssemblyOpt)
   at Roslyn.Utilities.CorLightup.Desktop.AssemblyResolveWrapper.Stub(Object sender, Object resolveEventArgs)
   at System.AppDomain.OnAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
   --- End of inner exception stack trace ---

I also tried installing my own assembly resolver, but couldn't get rid of this error. It's basically impossible to run any of my code in C# Interative at this point. This was not the case with VS Update 1 CTP.

For the sake of completeness, here's a warning that C# Interactive generates when it detects conflicting assembly versions:

untitled

This occurs only if I supply a binding redirect to FSharp.Core in app.config, otherwise the session would crash before this point.

Are there any workarounds for this? With just a few 3rd party deps, C# interactive quickly stops being useful because of this issue -- even when initializing from a project that builds and runs.

I am also having this problem. Is there a workaround or fix for this issue?

There is a workaround -- you can add .config file for InteractiveHost.exe with binding redirects:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies\InteractiveHost.exe.config

This is still happening, any news on when/if it's going to be fixed?
As others have said, for big projects where you want to try stuff fast C# interactive becomes useless.

Was this page helpful?
0 / 5 - 0 ratings