Tomas Jansson
Tomas Jansson

Reputation: 23472

C# project reference F# class lib in netcoreapp3.1

I've just created a simple class lib in F# that has the following fsproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Dto.fs" />
  </ItemGroup>

</Project>

Now I want to reference this in a C# project that has the following csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.2.0" />
    <PackageReference Include="Serilog" Version="2.10.0" />
    <PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
    <PackageReference Include="Serilog.Sinks.Splunk" Version="3.6.0" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\<path>\<to>\<file>.fsproj" />
  </ItemGroup>

</Project>

In the controller I now try to references the types in the F# class lib, but I do get the following compiler error:

Controllers/ProviderController.cs(4,53): error CS0234: The type or namespace name 'Types' does not exist in the namespace 'App.Api' (are you missing an assembly reference?) [/app/src/some more path Api/File.csproj] Controllers/ProviderController.cs(22,28): error CS0246: The type or namespace name 'Provider' could not be found (are you missing a using directive or an assembly reference?) [/homepath.csproj]

The actual controller looks like this:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NamespaceTo.Types.Dto;

namespace Api.Controllers
{
    [ApiController]
    [Route("[controller]")]
    [ApiVersion("1.0")]
    public class ProviderController : ControllerBase
    {
        private readonly ILogger<ProviderController> _logger;

        public ProviderController(ILogger<ProviderController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<Provider> Get()
        {
            return null;
        }
    }
}

It seems like the F# project isn't recognized at all since I don't get any intellisense on the types defined in F#. The build also fails as mentioned. Anything I'm missing to use F# types in a C# netcoreapp3.1 project?

The Dto.fs file in the F# project:

module Api.Types.Dto
open System

type Provider = {
    Id: string
    Name: string
    Logo: string
}

type Text = {
    Short: string
    Long: string
}

type ProductTexts = {
    Default: Text
    Alternatives: Text
}

type ProductAlternative = {
    Id: string
    IsDefault: bool
    Priority: int
    ContractLength: int
    MonthlyPrice: float
    EffectiveRate: float
    StartupFee: float
    MonthlyFee: float
    TotalPrice: float
    TotalCost: float
}

type Product = {
    Id: string
    Name: string
    Priority: int
    Provider: Provider
    Texts: ProductTexts
    MinimumAmount: float
    MaximumAmount: float
    Alternatives: ProductAlternative list
}

type ProductResponse = {
    Updated: DateTime
    ArticleId: string
    Price: float
    Currency: string
    OperatingChain: string
}

type PaymentOption = {
    ArticleIds: string list
    Product: Product
}

type PaymentOptionsResponse = PaymentOption list

Update:

I do have the same issue when I try to use the project from another F# console app.

Upvotes: 2

Views: 255

Answers (1)

nffa
nffa

Reputation: 56

As noted on Slack:
An initial concern is going to be that Api.Types.Dtois a top-level module and not namespace - this is implicitly using the namespace Api.Types and adding the Dto module to it.
C# sees Dto therefore as a type, not a namespace that can be opened - and the inner types such as Provider are just that, to C#, nested types.

There are two resolution paths here: The first is to open the namespace: using Api.Types and then dot into the nested types: Dto.Provider
The second is to using static Api.Types.Dto

Upvotes: 4

Related Questions