【问题标题】:Should one wrap type providers containing values that have side effects inside a class?一个包装类型提供程序是否应该包含在类中具有副作用的值?
【发布时间】:2018-11-04 20:00:14
【问题描述】:

我正在尝试在我的代码中实现 F# coding conventions 页面中的出色建议

https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/conventions.

Use classes to contain values that have side effects 部分特别有趣。它说

There are many times when initializing a value can have side effects, such as instantiating a context to a database or other remote resource. It is tempting to initialize such things in a module and use it in subsequent functions.

并提供了一个例子。然后指出了这种做法的三个问题(由于篇幅不足我省略了,但可以在链接的文章中看到)并建议使用简单的类来保存依赖关系。

我想知道应该如何对待类型提供程序?例如,如果我有以下代码,

[<Literal>]
let projDataPath = __SOURCE_DIRECTORY__ + @"\data\"

[<Literal>]
let configPath = projDataPath + "config.json"

type Cnfg = JsonProvider<Sample=configPath>
let config = Cnfg.Load(configPath)

使用类型提供程序来初始化值是否会遇到与值初始化相关的问题以及文章中描述的副作用?

换句话说,我应该将类型提供程序包装在一个类中吗?

【问题讨论】:

    标签: class f# type-providers side-effects


    【解决方案1】:

    您通常根本不应该将类型提供者的实例或其提供的类型公开给消费者。除了可能由非 F# .NET 使用者引起的潜在互操作性问题外,类型提供程序的实例通常表示您的应用程序正在管理的某些私有状态或资源的接口。作为一般规则,最好从消费者那里抽象出底层资源,并提供一个最适合问题域的模型。

    链接的文章特别警告不要将具有有限生命周期的类的实例捕获为模块中的绑定,因为绑定是不可变的,并且实例在其生命周期结束时将变为无效。这相当于在 C# 类中拥有 DbContext 或类似实例作为 static readonly 成员。它会被静态构造函数初始化,但永远不会改变,即使数据库连接关闭并且DbContext 实例不再有用。

    【讨论】:

    • 谢谢。这说明了这一点。我还有另一个相关问题,稍后我会发布。
    猜你喜欢
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多