簡體   English   中英

知道為什么在 F# 中跳過 C# 擴展調用嗎?

[英]Any idea why that C# extension call is skipped in F#?

由於某些原因,在調試 F# Giraffe 應用程序時, services.AddSingleton<IHostedService, CommandConsumer> |> ignorelet configureServices (services : IServiceCollection) services.AddSingleton<IHostedService, CommandConsumer> |> ignore

有點令人沮喪的是程序編譯,所以我希望程序能夠在該行的斷點處停止,但事實並非如此。

奇怪的是,如果我使用擴展方法的完整命名空間,那么斷點有效... Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton<IHostedService, CommandConsumer>(services) |> ignore

Program.fs的源代碼:

module Rm.Accounting.Workflows.Api.App

open System
open System.Threading
open System.Threading.Tasks
open System.IO
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Logging
open Microsoft.Extensions.DependencyInjection
open Giraffe
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.Hosting

type CommandConsumer()=
    inherit BackgroundService()

    override __.ExecuteAsync(cancellationToken : CancellationToken) =
        Task.CompletedTask


let webApp = choose [
                GET >=>
                    choose [
                        route "/" >=> redirectTo false "/health"
                    ]
                setStatusCode 404 >=> text "Not Found" ]

let errorHandler (ex : Exception) (logger : ILogger) =
    logger.LogError(ex, "An unhandled exception has occurred while executing the request.")
    clearResponse >=> setStatusCode 500 >=> text ex.Message

let configureApp (app : IApplicationBuilder) =
    app.UseHealthChecks(PathString("/health")) |> ignore
    let env = app.ApplicationServices.GetService<IHostingEnvironment>()
    (match env.IsDevelopment() with
    | true  -> app.UseDeveloperExceptionPage()
    | false -> app.UseGiraffeErrorHandler errorHandler)
        .UseHttpsRedirection()
        .UseStaticFiles()
        .UseGiraffe(webApp)

let configureServices (services : IServiceCollection) =
    // That line below stops the debugger if there a breakpoint.
    // Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton<IHostedService, CommandConsumer>(services)
    // |> ignore
    // The line does not stop the debugger with a breakpoint while the one above can, weird.
    services.AddSingleton<IHostedService, CommandConsumer> |> ignore
    services.AddHealthChecks() |> ignore
    services.AddGiraffe()      |> ignore


let configureLogging (builder : ILoggingBuilder) =
    builder.AddFilter(fun l -> l.Equals LogLevel.Error)
           .AddConsole()
           .AddDebug() |> ignore

[<EntryPoint>]
let main _ =
    let contentRoot = Directory.GetCurrentDirectory()
    let webRoot     = Path.Combine(contentRoot, "WebRoot")
    WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(contentRoot)
        .UseIISIntegration()
        .UseWebRoot(webRoot)
        .Configure(Action<IApplicationBuilder> configureApp)
        .ConfigureServices(configureServices)
        .ConfigureLogging(configureLogging)
        .Build()
        .Run()
    0

services.AddSingleton<IHostedService, CommandConsumer> |> ignore是不正確的語法,如果您分解所涉及的類型,您可以看到這一點。

services.AddSingleton<IHostedService, CommandConsumer>Func<unit, IServiceCollection> ,這意味着它是一個尚未被調用的函數。

然后ignore接收該函數並且不使用它做任何事情。

為了向服務注冊單例,您實際需要的語法是services.AddSingleton<IHostedService, CommandConsumer>() |> invoke ,意思是“執行 AddSingleton 調用並忽略返回值。

您可以使用services.AddHostedService(CommandConsumer) |> ignore而不是services.AddSingleton<IHostedService, CommandConsumer>() |> ignore並且CommandConsumer將位於托管后台服務的單例中。 有關主題的討論,請參閱此問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM