简体   繁体   中英

Why does Giraffe/AspNetCore + SignalR dependency injection fail to resolve a MailboxProcessor singleton?

I'm setting up a simple Giraffe app with one or two endpoints and a SignalR hub. What I have is like this:

type JsonBlob = JsonProvider<"Blob.json">
type Message = 
    | GetBlobs of AsyncReplyChannel<JsonBlob.Root list>
    | PostBlob of JsonBlob.Root

type JsonBlobHub(agent : MailboxProcessor<Message>) =
    inherit Hub()
    member self.RespondToClient() =
        let blobs = agent.PostAndReply(GetBlobs)
        self.Clients.All.SendAsync("ReceiveBlobList", blobs)

let agentFactory(serviceProvider : IServiceProvider) =
    let thing = serviceProvider.GetService<Thing>()
    MailboxProcessor.Start(fun (inbox : MailboxProcessor<Message>) ->
        /* loop implementation */
    )

// other stuff
let configureApp (app : IApplicationBuilder) =
    app.UseSignalR(fun routes -> routes.MapHub<JsonBlobHub>(PathString "/blobhub")) |> ignore
    app.UseGiraffe webApp // webApp defined elsewhere, not important

let configureServices (services : IServiceCollection) =
    services.AddSingleton<MailboxProcessor<Message>>(agentFactory) |> ignore
    services.AddGiraffe() |> ignore
    services.AddSignalR() |> ignore

let main argv =
    WebHostBuilder() =
        .UseKestrel()
        .UseWebRoot("WebRoot")
        .Configure(Action<IApplicationBuilder> configureApp)
        .ConfigureServices(configureServices)
        .ConfigureLogging(configureLogging)
        .Build()
        .Run
    0

When the SignalR client connects to /blobhub , the connection is closed unexpectedly because the app fails to resolve MailboxProcessor<Message> while trying to activate the BlobHub class.

I'm a bit stumped, however, because I've clearly registered the MailboxProcessor<Message> type in the container in the configureServices function. Does anyone see a problem in this code? Or maybe I'm assuming that these things should work, and there's some reason that they shouldn't that I'm not aware of?

Well....it turns out that I did a stupid thing and accidentally had two definitions of Message . My JsonBlobHub was using one definition while agentFactory and configureServices were using another definition. Once I removed one of the definitions of Message the DI container resolved the activation of JsonBlobHub as you would expect.

I would say that this wound up being a waste of time, but it did actually lead to a nice little self-contained example of using F#, Giraffe, ASP.NET Core, and SignalR together, and demonstrating that all the pieces play nicely together.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM