mbraceproject / FsPickler

A fast multi-format message serializer for .NET
http://mbraceproject.github.io/FsPickler/
MIT License
323 stars 54 forks source link

.netcore support? #83

Closed cloudRoutine closed 6 years ago

cloudRoutine commented 7 years ago

I started building some netcore F# editor tooling based on VFPT a while back and I was disappointed to see that I couldn't continue using FsPickler for it.

Has the lack of reflection support been the roadblock preventing FsPickler from targeting netcore ? Because now the NETStandard.Library 2.0.0 beta is available on myget along with these other reflection libs that aren't part of the standard lib -

So hopefully everything you need to make the jump is now available.

eiriktsarpalis commented 7 years ago

I won't be spending effort in supporting .NET core before I see convincing evidence of stability in both the APIs and tooling. I did yield to the pressure and accepted a PR in Argu which added .NET core support and my experience has been overwhelmingly negative since. The burden of supporting a bifurcated platform is too big.

buybackoff commented 7 years ago

I looked into this because I am a little interested in Vagabond on .NET Core (Mono.Cecil already supports netstandard1.3). I could instantly build FsPickler using the newest dotnet restore+build+pack tooling for net45, but for 1.6 (which is the minimum what F# supports) the file from TypeShape is the main issue - it uses reflection directly on GetType(), while netstandard reflection packages work only with .GetTypeInfo().

For netstandard I find the "mainstream" MSFT tooling very convenient even for F#, and it could be very easily used as the final step to pack NuGets. Below is the .fsproj file. It could co-exist with the old 14 format, and VS14/VS15 could work on old MSBuild tooling v.14 during design-time. There is a thing with F# compiler that it stops after 100 errors, so I couldn't quickly find what other packages and API are missing (other than the TypeShape file issue) and just stopped yesterday... But at least for NuGet packaging the .NET Core build tools work great.

The project file below builds if you remove netstandard1.6 from the targets. Of cause it doesn't make any sense for this issue - but my point is that tooling is there already, only code needs to change to a common API or to #ifs.

(and BTW, without OPTIMIZE_FSHARP the build breaks even for net45)

FsPickler.2017.fsproj

<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
    <Import Project="..\..\common.props" />
    <PropertyGroup>
        <TargetFrameworks>net45;netstandard1.6</TargetFrameworks>
        <AssemblyName>FsPickler</AssemblyName>
        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
    </PropertyGroup>

    <ItemGroup>
        <Compile Include="..\..\paket-files\eiriktsarpalis\TypeShape\src\TypeShape\TypeShape.fs">
            <Paket>True</Paket>
            <Link>TypeShape/TypeShape.fs</Link>
        </Compile>
        <Compile Include="AssemblyInfo.fs" />
        <Compile Include="Utils\CsharpProxy.fs" />
        <Compile Include="Utils\Utils.fs" />
        <Compile Include="Utils\Emit.fs" />
        <Compile Include="Utils\Reflection.fs" />
        <Compile Include="Utils\ShallowCopy.fs" />
        <Compile Include="Utils\Hashing.fs" />
        <Compile Include="Pickler\Types.fs" />
        <Compile Include="Pickler\PickleFormat.fs" />
        <Compile Include="Pickler\ReflectionCache.fs" />
        <Compile Include="Pickler\Pickler.fsi" />
        <Compile Include="Pickler\Pickler.fs" />
        <Compile Include="Pickler\PrimitivePicklers.fs" />
        <Compile Include="Pickler\CompositePickler.fs" />
        <Compile Include="Pickler\UnionCaseHelper.fs" />
        <Compile Include="Pickler\ReflectionPicklers.fs" />
        <Compile Include="Combinators\Wrappers.fs" />
        <Compile Include="Combinators\Sequence.fs" />
        <Compile Include="Combinators\Array.fs" />
        <Compile Include="Combinators\Tuple.fs" />
        <Compile Include="Combinators\FSharpList.fs" />
        <Compile Include="Combinators\DotNetTypes.fs" />
        <Compile Include="Combinators\FSharpTypes.fs" />
        <Compile Include="Combinators\Collections.fs" />
        <Compile Include="PicklerGeneration\PluginRegistry.fs" />
        <Compile Include="PicklerGeneration\PicklerEmit.fs" />
        <Compile Include="PicklerGeneration\FieldPicklers.fs" />
        <Compile Include="PicklerGeneration\ISerializablePickler.fs" />
        <Compile Include="PicklerGeneration\DataContractPickler.fs" />
        <Compile Include="PicklerGeneration\FSharpTypeGen.fs" />
        <Compile Include="PicklerGeneration\CustomPickler.fs" />
        <Compile Include="PicklerGeneration\PicklerGenerator.fs" />
        <Compile Include="PicklerGeneration\PicklerResolution.fs" />
        <Compile Include="PicklerGeneration\PicklerCache.fs" />
        <Compile Include="Format\BinaryFormat.fs" />
        <Compile Include="Format\XmlFormat.fs" />
        <Compile Include="FsPickler\RootSerialization.fs" />
        <Compile Include="FsPickler\ObjectSizeCounter.fs" />
        <Compile Include="FsPickler\Serializer.fs" />
        <Compile Include="FsPickler\TextSerializer.fs" />
        <Compile Include="FsPickler\BinarySerializer.fs" />
        <Compile Include="FsPickler\XmlSerializer.fs" />
        <Compile Include="FsPickler\FsPickler.fs" />
        <Compile Include="FsPickler\Combinators.fs" />
        <Compile Include="FsPickler\ExtensionMethods.fs" />
        <None Include="paket.template" />
        <None Include="paket.references" />
        <None Include="Test.fsx" />
    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
        <Reference Include="System" />
        <Reference Include="System.Core" />
        <Reference Include="System.Numerics" />
        <Reference Include="System.Runtime.Serialization" />
        <Reference Include="System.Xml" />
    </ItemGroup>

    <ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">
        <PackageReference Include="System.Runtime">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Reflection">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Reflection.Emit">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Reflection.Emit.ILGeneration">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Reflection.Emit.Lightweight">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Reflection.Extensions">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Reflection.TypeExtensions">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Runtime.Serialization.Xml">
            <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="System.Runtime.Serialization.Formatters">
            <Version>4.3.0</Version>
        </PackageReference>
        <!-- OTHER PACKAGES MAYBE NEEDED -->
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="FSharp.Core" Version="4.2.*" />
        <PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" />
    </ItemGroup>
</Project>

common.props

<Project>
  <PropertyGroup>
    <VersionPrefix>3.3.0</VersionPrefix>
    <VersionSuffix></VersionSuffix>
    <VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
    <PackageTags></PackageTags>
    <Product>FsPickler</Product>
    <RepositoryType>git</RepositoryType>
    <RepositoryUrl>https://github.com/mbraceproject/FsPickler/</RepositoryUrl>
    <Authors></Authors>
    <Company />
    <Product />
    <Copyright></Copyright>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn),1591</NoWarn>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
  </PropertyGroup>

  <PropertyGroup>
    <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net45|AnyCPU'">
    <DefineConstants>TRACE;NET45;PROTECT_STACK_OVERFLOWS;OPTIMIZE_FSHARP;EMIT_IL</DefineConstants>
    <OutputPath>..\..\bin\</OutputPath>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net45|AnyCPU'">
    <DefineConstants>TRACE;DEBUG;NET45;PROTECT_STACK_OVERFLOWS;OPTIMIZE_FSHARP;EMIT_IL</DefineConstants>
    <OutputPath>..\..\bin\</OutputPath>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard1.6|AnyCPU'">
    <DefineConstants>TRACE;COREFX;PROTECT_STACK_OVERFLOWS;OPTIMIZE_FSHARP;EMIT_IL</DefineConstants>
    <OutputPath>..\..\bin\</OutputPath>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard1.6|AnyCPU'">
    <DefineConstants>TRACE;DEBUG;COREFX;PROTECT_STACK_OVERFLOWS;OPTIMIZE_FSHARP;EMIT_IL</DefineConstants>
    <OutputPath>..\..\bin\</OutputPath>
  </PropertyGroup>
</Project>
eiriktsarpalis commented 6 years ago

Recent developments in .NET core probably mean that porting FsPickler will not be happening soon https://github.com/dotnet/corefx/issues/19119

jackfoxy commented 6 years ago

How about support of .NET 4.7? I just discovered I cannot use FsPickler in an Azure function. I can't tell the exact reason, but it is either because it is built for .NET 4.5, or the problem with System.Tuple having changed. I naively tried to build the project in 4.7, and discovered problems in Combinators\Tuple.fs with how System.Tuple is now defined.

eiriktsarpalis commented 6 years ago

I think the build failure is due to a bug in the latest release of the F# compiler. The assumption is that this will be fixed in the next release. What is the error you are seeing when running the current build in net47? On Mon, 27 Nov 2017 at 01:43, Jack Fox notifications@github.com wrote:

How about support of .NET 4.7? I just discovered I cannot use FsPickler in an Azure function. I can't tell the exact reason, but it is either because it is built for .NET 4.5, or the problem with System.Tuple having changed. I naively tried to build the project in 4.7, and discovered problems in Combinators\Tuple.fs with how System.Tuple is now defined.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/mbraceproject/FsPickler/issues/83#issuecomment-347048824, or mute the thread https://github.com/notifications/unsubscribe-auth/ACrts4IAlQHdY2CJS56hInuXxSDxFmNqks5s6fekgaJpZM4Mb-e6 .

jackfoxy commented 6 years ago

In Tuple.fs

p1.Write w "Item1" tuple.Item1 The field, constructor or member 'Item1' is not defined.

new Tuple<_,_,_,_,_,_,_,_>(t1,t2,t3,t4,t5,t6,t7,rest) 'new' may only be used with named types

eiriktsarpalis commented 6 years ago

This is due to this F# compiler bug https://github.com/Microsoft/visualfsharp/pull/3729

cmeeren commented 6 years ago

Now that VS15.5 has come out with proper F# support for .NET Standard and Core, could you consider releasing this for .NET Standard?

Note it currently seems to work fine in .NET Standard 2.0 (but is installed using .NET 4.6.1, so gives a warning.)

darting commented 6 years ago

Hi any news for this? thanks.