将 C# 数组类型的 Web 生成器转换为 F#

Convert C# Array type web builder to F#

我是 F# 的新手,正在尝试将以下 Service Fabric Asp.Net 核心代码从 C# 转换为 F#,但失败得很厉害。有人可以帮忙吗?

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[]
        {
            new ServiceInstanceListener(serviceContext =>
                new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
                {
                    ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                    return Microsoft.AspNetCore.WebHost.CreateDefaultBuilder()
                                .ConfigureAppConfiguration((builderContext, config) =>
                                {
                                    config.SetBasePath(builderContext.HostingEnvironment.ContentRootPath);
                                    config.AddJsonFile("appsettings.json", false);
                                    config.AddJsonFile($"appsettings.{builderContext.HostingEnvironment.EnvironmentName}.json", true);
                                    config.AddJsonFile("PackageRoot/Config/eventFlowConfig.json", optional: true, reloadOnChange: true);
                                    config.AddEnvironmentVariables();
                                })
                                .ConfigureServices(
                                    services =>
                                    {
                                        services.AddSingleton<StatelessServiceContext>(serviceContext);
                                    })
                                .UseStartup<Startup>()
                                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                                .UseUrls(url)
                                .Build();
                }))
        };
    }

F#

module Service

open Microsoft.ServiceFabric.Services.Runtime
open Microsoft.ServiceFabric.Services.Communication.Runtime
open Microsoft.ServiceFabric.Services.Communication.AspNetCore
open Microsoft.AspNetCore.Hosting

type Service(context) =
    inherit StatelessService(context)

    let builder = (fun url listener ->  
        Microsoft.AspNetCore.WebHost.CreateDefaultBuilder().UseUrls(url).Build())

    let kestrelCommunicationListener ctx builder = new KestrelCommunicationListener(ctx, "ServiceEndPoint", builder)
    let serviceInstanceListener context ()  =  new ServiceInstanceListener(context kestrelCommunicationListener);

    override __.CreateServiceInstanceListeners() = 
        seq {
                yield serviceInstanceListener(fun context -> kestrelCommunicationListener builder)
            }

将 lambda 拆分为方法我能够得到这个

module Service

open Microsoft.ServiceFabric.Services.Runtime
open Microsoft.ServiceFabric.Services.Communication.Runtime
open Microsoft.ServiceFabric.Services.Communication.AspNetCore
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Configuration
open System.Fabric

let setBasePath path config =
    FileConfigurationExtensions.SetBasePath (config, path)

let addJson path optional reloadOnChange config =
    JsonConfigurationExtensions.AddJsonFile(config, path, optional, reloadOnChange)

type Service(context) =
    inherit StatelessService(context)

    let configureAppConfiguration (builder : IWebHostBuilder) =
        builder.ConfigureAppConfiguration(fun builderContext config ->
            let envAppsettings = sprintf "appsettings.%s.json" builderContext.HostingEnvironment.EnvironmentName

            config
                |> setBasePath builderContext.HostingEnvironment.ContentRootPath
                |> addJson "appsettings.json" false false
                |> addJson envAppsettings true false
                |> addJson "PackageRoot/Config/eventFlowConfig.json" true true
                |> EnvironmentVariablesExtensions.AddEnvironmentVariables
                |> ignore
        )

    let configureServices (ctx:ServiceContext) (builder : IWebHostBuilder) =
        builder.ConfigureServices(fun s -> s.AddSingleton<StatelessServiceContext>(ctx))

    let useStartup (builder: IWebHostBuilder) =
        builder.UseStartup<Startup>()

    let useServiceFabricIntegration listener (builder: IWebHostBuilder) =
        builder.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)

    let useUrl url (builder: IWebHostBuilder) =
        builder.UseUrls([|url|])

    let build (builder: IWebHostBuilder) =
        builder.Build()    

    let builder (ctx:ServiceContext) = fun (url:string) (listener:AspNetCoreCommunicationListener) ->  

            Microsoft.AspNetCore.WebHost.CreateDefaultBuilder()
                |> configureAppConfiguration
                |> configureServices ctx
                |> useStartup
                |> useServiceFabricIntegration listener
                |> useUrl url
                |> build


    let kestrelCommunicationListener (ctx:ServiceContext) =
        let build  = builder ctx
        let f = new System.Func<string, AspNetCoreCommunicationListener, IWebHost>(build)

        new KestrelCommunicationListener(ctx, "ServiceEndPoint", f) :> ICommunicationListener

    let serviceInstanceListener () =  new ServiceInstanceListener(fun ctx -> kestrelCommunicationListener ctx)    

    override __.CreateServiceInstanceListeners() = 

        seq {
                yield serviceInstanceListener()
            }