使用FP / F#方式处理状态的功能

时间:2019-01-10 07:02:13

标签: f# c#-to-f#

这里有一些接口IOrderSender,它定义了具有某些实现KafkaOrderSender的业务操作(订单发送)(通过本示例中的Kafka生产者)。

在保留原始OOP样式的情况下,代码是从C#重写的:

type CustomerId = string

type IOrderSender =
    abstract SendOrders: CustomerId -> Order list -> unit

type KafkaOrderSender(config: IConfiguration) =
    let streamConfig = config.GetSection("OrderStream")

    let producerConfig = new ProducerConfig(BootstrapServers = streamConfig.GetValue("BootstrapServers"))
    let producer = new Producer<string, string>(producerConfig)

    let ordersTopic: string = streamConfig.GetValue("Topic")

    interface IOrderSender with
        member this.SendOrders customerId orders =
            for order in orders do
                let orderJson = JsonConvert.SerializeObject<Order>(order)
                let msg = new Message<string, string>(Key = customerId, Value = orderJson)
                do producer.BeginProduce(ordersTopic, msg)

    interface IDisposable with
        member this.Dispose() =
            do producer.Flush(CancellationToken.None)
            do producer.Dispose()

这里有:

  • 界面(IOrderSender

  • 实现(KafkaOrderSender

  • 一个外部依赖项(IConfiguration

  • 内部状态(producer,需要在调用之间共享)

  • 状态需要关闭/处理(IDisposable

此接口和实现已在某些DI容器中注册(例如带有Giraffe的ASP.NET Core):

let configureServices (services : IServiceCollection) =
    services.AddGiraffe() |> ignore
    services.AddSingleton<IOrderSender, KafkaOrderSender>() |> ignore

然后通过DI解析此对象并在应用程序逻辑中使用:

let handleOrders (customerId: CustomerId) (orders: Orders): HttpHandler =
    fun (next : HttpFunc) (ctx : HttpContext) ->
        // Resolve
        let orderSender = ctx.GetService<IOrderSender>()
        // Use
        do orderSender.SendOrders customerId orders
        return! text "OK" next ctx

是否有更好的方法以一种更惯用的功能方式(模块代替类,部分应用程序代替通过构造函数的依赖关系)实现IOrderSender?

在这种情况下,如何处理共享状态(生产者)以及如何实现共享状态的处置?

0 个答案:

没有答案