MissingMethodException when using Unquote asserts - f#

I'm trying to use unquote with NUnit as the test runner. The test case is taken from Getting Started and works as expected when run outside of NUnit:
namespace FsTest.Tests
open NUnit.Framework
open Swensen.Unquote
[<TestFixture>]
module Example =
[<Test>]
let foo() =
test <# (1+2)/3 = 1 #>
Under NUnit I get this exception:
FsTest.Tests.Example.foo: System.MissingMethodException : Method not
found:
'System.Tuple2<Microsoft.FSharp.Collections.FSharpList1,Microsoft.FSharp.Quotations.FSharpExpr>
Internal.reduceFullyAndGetLast(Microsoft.FSharp.Quotations.FSharpExpr)'.
I'd like to know if there's anything wrong with the code above and how I could make it work. Unquote's raise fail for me in the same way if that helps.

Based on the description of your problem, I suspect you need to configure your NUnit project with an FSharp.Core binding redirect from version 4.0.0.0 to version 4.3.0.0 since the latest version of Unquote is built for .NET 4.0 and your test project targets .NET 4.5.
See this Unquote issue for details. I believe your configuration would look something like
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity
name="FSharp.Core"
publicKeyToken="b03f5f7f11d50a3a"
culture="neutral"/>
<bindingRedirect
oldVersion="2.0.0.0"
newVersion="4.3.0.0"/>
<bindingRedirect
oldVersion="4.0.0.0"
newVersion="4.3.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I'm not sure exactly where you would need to put this for an NUnit project, but maybe in the config file specified through the Project Editor?
Unfortunately, I don't have VS2012 installed and so I am somewhat crippled in my ability to really diagnose this issue for you.

Related

FSharp.Data missing method exception

I am trying to resolve a MissingMethodException in a pre-compiled F# Azure Function. The exception is thrown when I call an extension method from FSharp.Data.CssSelectorExtensions.
The function is defined in a .Net Framework 4.6.2 class library. I am using the current versions of FSharp.Core (4.2.3) and FSharp.Data (2.3.3). (I have tried older versions of both but the problem persists.) I have added a binding redirect for FSharp.Core per the standard guidance for this kind of problem. The code compiles cleanly but fails when it is executed. It also fails if I attempt to invoke the extension method directly as a simple static method.
Any guidance on how I can get rid of this exception would be much appreciated!
Function Code
module httpfunc
open System.Net
open System.Net.Http
open Microsoft.Azure.WebJobs.Host
open FSharp.Data
open FSharp.Data.CssSelectorExtensions
let Run(req: HttpRequestMessage, log: TraceWriter) =
async {
let doc = HtmlDocument.Load("https://google.com")
let node = doc.CssSelect("div.ctr-p") // <-- method is missing
return req.CreateResponse(HttpStatusCode.OK)
} |> Async.RunSynchronously
Exception Message
mscorlib: Exception while executing function: Functions.httpfunc.
mscorlib: Exception has been thrown by the target of an invocation.
fsfuncs: Method not found: 'Microsoft.FSharp.Collections.FSharpList`1<FSharp.Data.HtmlNode> CssSelectorExtensions.CssSelect(FSharp.Data.HtmlDocument, System.String)'.
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.1.0" newVersion="4.4.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FSharp.Core" version="4.2.3" targetFramework="net462" />
<package id="FSharp.Data" version="2.3.3" targetFramework="net462" />
...
</packages>
.fsproj
<Project ToolsVersion="15.0" ... />
<PropertyGroup>
<RootNamespace>fsfuncs</RootNamespace>
<AssemblyName>fsfuncs</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFSharpCoreVersion>4.4.1.0</TargetFSharpCoreVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Name>fsfuncs</Name>
</PropertyGroup>
...
</Project>
Edit
On Fyodor Soikin's advice I've determined that multiple versions of FSharp.Core.dll are being loaded: one from the GAC and one from the NuGet packages folder.
The execution engine behind Azure Functions already loads FSharp.Core.dll (because it depends on F# compiler services to run your F# scripts) and I think you will always get the version of FSharp.Core.dll that is specified by the execution engine's app.config, which is 4.4.0.0.
I might be missing something, but I think your best chance is to make your function use version 4.4.0.0. Could you try removing the explicit FSharp.Core reference? That way, the runtime should load just the (already pre-loaded) version of FSharp.Core.

TypeLoadException: From C# code that attempts to interop with F# code

I am struggling to resolve this runtime exception from my C# PCL that references an F# PCL:
Unhandled Exception:
System.TypeLoadException: Could not resolve type with token 0100001d
(from typeref, class/assembly Microsoft.FSharp.Core.FSharpResult`2,
FSharp.Core, Version=3.259.41.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a) occurred
NOTE:
I have ensured that my C# and F# project reference the same FSharp.Core version.
I remember having to add an XML file for versioning whenever I my test projects in F# wouldn't play nice with my F# projects. Is this the same case?
I added the following to my app config on my Xamarin.Forms PCL:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-999.999.999.999" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
But I still receive the same error.
FSharpResult is (I assume) the Result<'TSuccess, 'TError> type that was introduced in FSharp 4.1 so you should get FSharp.Core Version 4.4.1.0.

FsUnit: Unable to test portable library due to it and test project having different F#.Core versions

I have a Portable Library, for which the FSharp.Core version is 3.7.4.0. Installing (in the Unit Test project) FsUnit installs, as a dependency, FSharp.Core version 3.1.2.5.
Due to this, using the portable library's functions in my Unit Test project, for example:
module StammaTests.PieceTests
open Stamma
open NUnit.Framework
open FsUnitTyped
[<Test>]
let ``Testing a Basic function`` () =
Piece.toChar Black King |> shouldEqual 'k'
yields error:
Result Message: System.IO.FileLoadException : Could not load file or assembly 'FSharp.Core, Version=3.7.4.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
located assembly's manifest definition does not match the assembly
reference. (Exception from HRESULT: 0x80131040)
Tried updating the FSharp.Core version from NuGet to 4.0.0.1 (even checking both projects when updating) and now even something simple like :
[<Test>]
let ``Testing the test`` () = 1 |> shouldEqual 1
doesn't work, giving this similar error.
Result Message: System.IO.FileLoadException : Could not load file or
assembly 'FSharp.Core, Version=4.3.1.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
located assembly's manifest definition does not match the assembly
reference. (Exception from HRESULT: 0x80131040)
And the error for the first failing test doesn't change.
I feel like I am missing something painfully obvious, and I found several people with similar problems, but I don't understand what they did to solve it (they all seem to have solved it ..) For example this one.
Edit
Both projects are libraries and I do not have an app.config file to add anything to.
Add a binding redirect in your app.config file to redirect all FSharp.Core bindings to your desired version. For example, to use version 4.4.0, your app.config file would look something like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I found a solution that actually worked here
Basically, adding an App.config to the test project, and writing the following:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.4.14350" newVersion="2.6.4.14350" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
It adds binding to both Fsharp.Core and NUnit.Framework, unlike the usual solutions where you only add a binding for Fsharp.Core.

how to use DotNetOpenAuth.Core, Version=4.3.0.0 with vs 2012

i'm using visual studio (2012 or 2013) with asp mvc 4
and it gives me the following error :
Could not load file or assembly 'DotNetOpenAuth.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
i need to use version 4.3.0.0 i installed it using nuget
I know I had problems with the System.Mvc dependency being of the wrong version. Adding the following assembly "rebinding" to your web.config solved the problem (note the version numbers):
<configuration>
<runtime>
<!-- When targeting ASP.NET MVC 3-4, this assemblyBinding makes MVC 1 and 2 references relink
to MVC 3-4 so libraries such as DotNetOpenAuth that compile against MVC 1 will work with it. -->
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Sidenote: I discovered DotNetOpenAuth.Ultimate that bundles everything into one single DLL! It's much much simpler to maintain that the default DotNetOpenAuth and its huge number of packages....

TFS Build 2012, ASP.NET MVC & MSB3247: Found conflicts between different versions of same dependent assembly

I'm getting the MS Build warning "MSB3247: Found conflicts between different versions of the same dependent assembly." when building the a web project (ASP.NET MVC4) under TFS Build 2012.
Consider app.config remapping of assembly "System.Web.Mvc, Culture=neutral, PublicKeyToken=31bf3856ad364e35" from Version "2.0.0.0" [] to Version "4.0.0.0" [XXXX\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll] to solve conflict and get rid of warning.
Consider app.config remapping of assembly "WebGrease, Culture=neutral, PublicKeyToken=31bf3856ad364e35" from Version "1.3.0.0" [] to Version "1.5.2.14234" [XXXX\packages\WebGrease.1.5.2\lib\WebGrease.dll] to solve conflict and get rid of warning.
Consider app.config remapping of assembly "Antlr3.Runtime, Culture=neutral, PublicKeyToken=eb42632606e9261f" from Version "3.4.1.9004" [] to Version "3.5.0.2" [XXXX\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll] to solve conflict and get rid of warning.
I know which references are causing these and that's not the problem. I have the relevant binding redirects in place in the web.config file, most of which are set by NuGet when referencing the relevant package(s).
Problem is this is a web project, and it is as if MSBuild is ignoring the binding redirects in the web.config file:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
</dependentAssembly>
</assemblyBinding>
</runtime>
This warning does occur in the local developer build, but not consistently every time.
The interesting thing is that if I add an app.config file to the web project and place the assembly redirects in there (still keeping the original redirects in the web.config file) the warning goes away, both locally and with TFS Build (where it happens consistently.).
WTF? Any ideas?
I have finally managed to isolate the root cause of this error and identify a few red-herrings.
First, it is a red herring that the issue does not occur where Visual Studio 2012 installed or does not happen on the developer workstations. While the issue occurs consistently on the build servers (TFS Build), it happens on the workstations too, provided the steps "Batch Clean All", followed "Build" are followed.
Second, I can now confirm that the culprit for the MSB 3247 warning is the Microsoft BCL Build Nuget Package:
Microsoft.Bcl.Build.1.0.10
It modifies the web application project file, adding the following Import:
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
If I comment it out of the project file, the issue on the local workstations and the TFS Build Servers goes away.
Unfortunately I do not know what the impact of commenting out the above really means. Can I leave it commented out - what will happen?
The reason this Microsoft.Bcl.Build NuGet package is part of the project is because it's marked as a dependency to the Microsoft.Net.Http NuGet package which we do use. Earlier versions of the Microsoft.Net.Http NuGet package did not have this dependency on Microsoft.Bcl and Microsoft.Bcl.Build packages.
Hope this helps someone.
PS: This has a corresponding, but so far unhelpful forum post here: http://social.msdn.microsoft.com/Forums/vstudio/en-US/faa1b607-50bb-48e3-bd5d-76f4fc02ad4c/ms-build-gives-warning-msb3247-found-conflicts-between-different-versions-of-same-dependent?forum=msbuild
I don't have the Bcl.Build stuff anywhere that I can see, and this is the exact error I'm getting on my 2013 TFS build server.
My warnings look like this:
C:\Program Files (x86)\MSBuild\12.0\bin\amd64\Microsoft.Common.CurrentVersion.targets (1635): Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file:
Which, I already had in my web.config, minus the culture= param, in both my web and api projects.
I'm sorry I don't have any answer for you, I've just gotten my first build to complete, and these are the last two warnings I'm getting.

Resources