【问题标题】:Module with shared state具有共享状态的模块
【发布时间】:2021-11-19 04:08:45
【问题描述】:

我目前正在用 F# 编写一个 ASP.NET Core 中间件。 基本上我想要实现它的方式是,服务对给定程序集中的已实现类型进行一次性扫描,并将结果放入字典中,然后中间件函数使用该扫描的结果来做一些工作。

显然,我不想为每个呼叫重做扫描。我想在应用程序启动时执行此操作(初始化字典),然后在每次调用时使用它,但我很难在 F# 中找到解决方案。

在 C# 中,我基本上会创建一个包含该字典的有状态类,然后我会让中间件类使用它。

它基本上是服务和中间件之间的共享状态,但我不知道如何在 F# 中解决这个问题,即使我要跳出函数范式。

【问题讨论】:

    标签: asp.net functional-programming f# middleware


    【解决方案1】:

    您的问题可能还不清楚其他问题,但让一些具有状态的共享代码(在应用程序启动时初始化)的最简单方法是将您的代码放入module。在模块中,您可以运行所需的任何内容,并且 F# 编译器确保在您从模块中访问任何内容之前运行它(它在静态构造函数中完成)。

    例如,您可以使用以下内容添加文件shared.fs

    module Shared
    
    let private things =
        printfn "Doing some initialization..."
        [ "a", 123 ] |> dict
    
    let fetchThing key = 
        things.[key]
    

    如果您将此作为项目中的第一个文件(它必须在引用它的其他文件之前),那么您可以从程序的其他部分调用Shared.fetchThing "a" -你会得到存储在字典中的值。

    【讨论】:

    • 过去我看到这种初始化代码可以在任何异常处理程序、日志系统或 GUI 启动并运行之前运行。我曾经遇到过这样的情况,当时 .NET 中的一些基本内容都无法按预期工作。我通常只使用它来初始化数据结构,如此处所示,并且我非常小心不要冒险引发任何异常。
    • @BentTranberg 是的,我同意这种做事方式有很多限制 - 例如。很难说初始化到底是什么时候发生的。在不了解 OP 的具体情况的情况下,我认为可能很难给出更好的建议。也许一个明智的选择是只使用一个调用Shared.init () 的主初始化块来填充字典,一旦其他东西被初始化(如果还有其他东西要初始化)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多