Should one wrap type providers containing values that have side effects inside a class?

廉价感情. 提交于 2020-01-05 02:32:25

问题


I am trying to implement in my code the excellent advice in the F# coding conventions page

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

The section Use classes to contain values that have side effects is particularly interesting. It says

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.

and provides an example. Then it points out three problems with this practice (I omit those for lack of space, but they can be seen at the linked article) and recommends using a simple class to hold dependencies.

I wonder how should type providers be treated? For example, if I have the following code,

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

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

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

using the type provider to initialize a value is subject to the problems associated to value initialization with side effects described in the article?

In other words, should I wrap the type provider inside a class?


回答1:


You should generally not expose instances of type providers or their provided types to consumers at all. Aside from the potential interoperability issues that may arise from non-F# .NET consumers, instances of Type Providers often represent an interface to some private state or resource that your application is managing. As a general rule, it is best to abstract the underlying resources from your consumer and present a model that best fits the problem domain.

The linked article is specifically warning against capturing instances of classes with a finite lifecycle as bindings in a module, because the bindings are immutable and the instance will become invalid when its lifecycle ends. This would be equivalent to having a DbContext or similar instance as a static readonly member in a C# class. It would be initialized by the static constructor, but could never change, even if the database connection becomes closed and the DbContext instance is no longer useful.



来源:https://stackoverflow.com/questions/50528864/should-one-wrap-type-providers-containing-values-that-have-side-effects-inside-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!