fsprojects / FSharp.Configuration

The FSharp.Configuration project contains type providers for the configuration of .NET projects.
http://fsprojects.github.io/FSharp.Configuration/
Other
114 stars 63 forks source link

0.5.5 causes YamlProvider to throw on type initializer #76

Open CumpsD opened 8 years ago

CumpsD commented 8 years ago

When upgrading to 0.5.5 the following code gives errors in Visual Studio at editing time:

type WebConfig = YamlConfig<"Web.yaml">

The error is: The type provider 'FSharp.Configuration.ConfigTypeProvider+FSharpConfigurationProvider' reported an error: The type initializer for '<StartupCode$FSharp-Configuration>.$FSharp.Configuration.YamlConfigTypeProvider' threw an exception

The input is a simple:

EventStore:
    ConnectionString: tcp://admin:changeit@127.0.0.1:1113

Although we tried debugging this with @vasily-kirichenko on slack, it seems to work when manually doing it in the test project (verified this myself as well)

However, I have reproduced it by changing the test project to use 0.5.5 from NuGet and using the above configuration file.

You clone this: https://github.com/CumpsD/FSharp.Configuration and open FSharp.Configuration.Tests.sln. You should see in YamlProvider.Tests.fs it gives errors

vasily-kirichenko commented 8 years ago

SharpYaml is shown like this in dotPeek:

image

Could it cause the exception? I know nothing about all this "portable" and "profileXXX" things.

vasily-kirichenko commented 8 years ago

I've unlisted 0.5.5 and 0.5.6 packages for now.

CumpsD commented 8 years ago

Fixed with https://github.com/fsprojects/FSharp.Configuration/commit/23dcf732e2ee371939c100d6692a526e151db77a

pchalamet commented 8 years ago

This merely looks like a definitive rollback of nuget dependencies on SharpYaml (back to lib folder with unknown assembly sources).

CumpsD commented 8 years ago

That's what they did yes, they did some debugging on slack but rolled it back for now because it broke for others, apparently the assembly needs to be in the same directory.

sergey-tihon commented 8 years ago

We have three options here 1) Leave everything as is - it just works) 2) We can add dependency to SharpYaml and pull latest version from NuGet and pack this version automatically to FSharp.Configuration NuGet package. It is relatively easy to do. 3) We actually can add SharpYaml dependency to FSharp.Configuration NuGet package, but it is require refactoring of the project like this http://bluemountaincapital.github.io/FSharpRProvider/devnotes.html to setup AssemblyResolve event handler that will help TP to find SharpYaml.dll

pchalamet commented 8 years ago

Fix for dependencies in nuspec (#77) should have fixed it. In 0.5.5 nuget could not correctly add the dependency on SharpYaml. In 0.5.6, in should be OK (I checked nuspec in nupkg), so upgrading nuget should have add correct reference on SharpYaml. I'm worried we prefer to have an assembly nobody has sources for. And if there is any bug fix inside, they should be forwarded upstream. This also implies it's not possible to use nuget SharpYaml without problem when using Fsharp.conf.

CumpsD commented 8 years ago

I'll re-open it for you guys to discuss further and decide on it.

@pchalamet the fix did not fix it because the dll was in the wrong directory, very like this: http://bluemountaincapital.github.io/FSharpRProvider/devnotes.html

When you use R provider via NuGet and the F# compiler references the R provider, it attempts to load it from the location where NuGet puts it. This is typically packages/RProvider.1.0.8/lib. This directory does not contain RDotNet.dll (which is installed in packages/R.NET.1.3.5/lib/net40) and so the loading could fail.

To avoid this, we need to make sure that the assembly that is loaded by the F# compiler (and Visual Studio) does not trigger loading of R.NET immediately - that

pchalamet commented 8 years ago

I will speculate but this looks like a "feature" in the F# type provider compiler infrastructure. I guess an assembly for a type provider is isolated when running type provider at compile time for security reason (and ignoring whatever is referenced to compile a project). Probably @dsyme could help on this :-)

Anyway, merging everything in one assembly with ILMerge could help (and Fake supports this out of the box) - this would probably provide an acceptable workaround for type provider infrastructure and enable using latest version of SharpYaml.

sergey-tihon commented 8 years ago

@pchalamet ILMerge can lead to issues in runtime, if you decide to use latest SharpYaml.dll and FSharp.Configuration.dll (which already has classes from older version of SharpYaml) in one project. It will crash in runtime.

The best solution is to setup AssemblyResolve that fix all issues, but it is require a bit of work :smirk:

78 propose changes very similar to your suggestion, just download latest version of SharpYamlfrom NuGet and pack it inside FSharp.Configuration NuGet package near TP dll during the release.