You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在F# ASP.NET Minimal API中使用键控服务注入属性?

纯F# + .NET 8 Minimal API 键控服务解决方案

1. 定义服务接口与实现

先创建键控服务的核心接口及具体实现类:

type IMessageService =
    abstract member GetMessage : unit -> string

// SMS服务实现
type SmsMessageService() =
    interface IMessageService with
        member _.GetMessage() = "This is an SMS notification"

// 邮件服务实现
type EmailMessageService() =
    interface IMessageService with
        member _.GetMessage() = "This is an Email notification"

2. 注册键控服务

在应用构建阶段完成带键服务的注册:

let builder = WebApplication.CreateBuilder(args)

// 注册键控单例服务
builder.Services.AddKeyedSingleton<IMessageService, SmsMessageService>("sms")
builder.Services.AddKeyedSingleton<IMessageService, EmailMessageService>("email")

let app = builder.Build()

3. 定义端点(规避Lambda属性丢失问题)

F#的Lambda表达式会被包装为Func实例,导致参数上的FromKeyedServices属性无法被ASP.NET Core识别,因此需采用静态方法或实例方法定义端点逻辑:

方式一:模块内静态方法

module MessageEndpoints =
    static member GetMessage(
        [<FromKeyedServices(Key = "{key}")>] messageService: IMessageService,
        [<FromRoute>] key: string) =
        messageService.GetMessage()

// 映射端点
app.MapGet("/message/{key}", MessageEndpoints.GetMessage)

方式二:类实例方法(适配复杂端点逻辑)

type MessageEndpointHandler() =
    member _.HandleMessage(
        [<FromKeyedServices(Key = "{key}")>] messageService: IMessageService) =
        messageService.GetMessage()

// 注册处理器类
builder.Services.AddTransient<MessageEndpointHandler>()

// 映射端点
app.MapGet("/message/{key}", (handler: MessageEndpointHandler) => handler.HandleMessage)

4. 验证效果

启动应用后,访问对应端点即可获取预期结果:

  • GET /message/sms 返回 This is an SMS notification
  • GET /message/email 返回 This is an Email notification

关键注意事项

  • 禁止用Lambda表达式定义带FromKeyedServices属性的端点参数,否则会因Func包装导致属性丢失,触发InvalidOperationException。
  • 使用静态/实例方法时,参数上的FromKeyedServices属性会被完整保留,ASP.NET Core可正常识别并注入对应键的服务。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 08:12:38