3
votes

I have created an F# library using the standard F# Portable Library option provided by VS2012 when creating a new project. The library is intended to be used by a C# program.

The F# library needs to accept data from the C# app that is encapsulated in a C# object. I have imported the C# dll containing the object into the F# library but get the following 2 errors:

The primary reference "DataStructures" could not be resolved because it has an indirect dependency on the framework assembly "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETPortable,Version=v4.0,Profile=Profile47". To resolve this problem, either remove the reference "DataStructures" or retarget your application to a framework version which contains "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".

and

The primary reference "DataStructures" could not be resolved because it has an indirect dependency on the framework assembly "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETPortable,Version=v4.0,Profile=Profile47". To resolve this problem, either remove the reference "DataStructures" or retarget your application to a framework version which contains "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".

In looking through the messages it is clear that there is a version incompatibility issues between mscorlib and System used in the F# and C# dlls. So I naively switched the F# references to the exact ones used by the C# dll. This momentarily resolved my error but as soon as I built it, the f# library's references were automatically switched back to their previous "portable" versions of mscorlib and System.

I can get around this by forcing the C# app to turn its data into Tuple<'t> before sending it to the f# dll and thus get rid of the C# dll dependency in this project, but I was hoping to avoid these transformations.

There is a post here base CLI library 'mscorlib' is binary-incompatible with the referenced F# core library which suggests pass explicit references to both on the command-line.

Is there some way to do this is an F# Portable Library? Or is there so other way to resolve these compatibility issues?

Edit: I have also checked that:

  1. Both dlls are targeting .net 4.5
  2. Both dlls' build options are set to standard "any cpu" settings
1
The problem here is that one version is targeting the portable version of .NET (works on Silverlight etc.) whilst the other is targeting standard .NET. - John Palmer
Indeed! This is the source of the problem, but cannot seem to get the F# library to target anything else despite explicitly setting the references. Each time I build it, it switches them back. I choose the F# Portable Library as opposed to the F# library because I thought it was the library of choice if you wanted it to function in a c# app. Visual studio labels it as A F# library that can run on Windows and Silverlight Have I misunderstood this? - Chris Tarn
I think you just want to use F# library. The portable one targets the .NET portable runtime, but the standard F# library should target the same .NET that C# targets by default. - John Palmer

1 Answers

3
votes

Based on John Palmer's comment above I did some research into what the F# Portable Library is used for.

According to Tao Liu in "F# for C# Developers"...

The Portable Class Library project supports a subset of assemblies from the .NET Framework, Silverlight, .NET for Windows Store apps, Windows Phone, and Xbox 360, and provides a Visual Studio template that you can use to build assemblies that run without modification on these platforms. If you don’t use a Portable Class Library project, you must target a single app type, and then manually rework the class library for other app types. With the Portable Class Library project, you can reduce the time and costs of developing and testing code by building portable assemblies that are shared across apps for different devices.

The Short answer: is basically what John Palmer said. Don't use an F# Portable Library in this case. Use an F# Library. Doing so resolved all my issues.

The slightly longer answer: If you want to use your F# Library in a WinRT app, or any other of the above cases the F# Portable Library seems to be the way to go. F# portable is really intended to be write once run anywhere dll but that comes at a price. ALL dependencies must also target the same portable subset of System and mscorlib. So, any C# dlls you use in an F# Portable Library also need to be in the form of C# Portable Class Library or you will run into the same problem.