为什么要使用Func <string>而不是仅使用string?

时间:2019-12-11 15:30:40

标签: c# .net azure-functions

为什么要使用 Func<string> 而不是 string

我的问题特别是关于this回购。

有问题的行是22:

    private static Func<string> getToken = () => Environment.GetEnvironmentVariable("GitHubToken", EnvironmentVariableTarget.Process);

getToken封装了一个没有参数的方法,并返回一个string为什么不简单地将此变量键入为字符串是什么原因?

为什么要使用 Func<string> 而不是 string

6 个答案:

答案 0 :(得分:5)

我可以看到这样做的五个原因:

  1. 当您要允许一个不仅会随时间变化的值时(您仍然可以使用属性来实现!),但是您需要检查以查找它的位置可能会发生变化。例如,默认情况下,您检查环境变量,但是在某处有一个用户选项,它将查找配置文件,Web服务或数据库表等。现在您可以换出函数调用,而不必检查每次在必须知道如何执行所有这些功能的函数中使用config选项。
  2. 这使得在async上下文中使用它变得更加容易,您可以在其中等待结果。您可以直接在任务中等待函数,而不必将属性包装为等待的方法。
  3. 他们想要函数语义而不是属性语义。这是一种选择,他们希望将函数调用作为类型的公共API而不是属性。那么,lambda(真的是expression bodied member)只是编写该方法的一种较短方法。
  4. 这是在新的default interface implementations in C# 8之前编写的,该代码提供了默认的实现,但实际上希望您“覆盖”它,并用自己的方法替换该方法,该方法可以查看所需的任何值。或者,即使他们使用的是C#8,也认为附加的接口不值得。
  5. 在依赖注入场景中更改实现会更容易,尽管希望这样做的人会使用接口代替。通常,您要注入整个类型,而不是单个方法。

答案 1 :(得分:2)

通过将其存储为Func<string>,每次访问变量时将调用Environment.GetEnvironmentVariable。这意味着如果Environment.GetEnvironmentVariable在后​​续调用中返回不同的值,您将获得新值。

据我所知,Environment.GetEnvironmentVariable对于同一输入将返回不同值的唯一方法是是否调用了Environment.SetEnvironmentVariable

答案 2 :(得分:2)

此处是存储库的作者。

使用此命令的主要原因是该类是静态的,而该属性是静态的。尽管环境变量可能会更改,但是直到重新启动实际的应用程序后,该变量才会反映出来。

我这样做的主要原因是,它永远都不能放在环境变量中。应将其保存在诸如Azure KeyVault(AWS HSM?)之类的秘密服务存储中。该值可能会更改,恕不另行通知,无需重新启动应用程序,并且将继续使用旧令牌,直到发生错误为止。

在这种情况下,需要做的就是将实现功能完全替换为可以正确保护数据的功能。

答案 3 :(得分:1)

通常,如果函数产生的值在程序执行期间可能发生变化,则可以使用Func<T>而不是T

它对于DI场景也很有用,在DI场景中,函数的使用者不在乎(或不应该知道...)值的来源。它只需要能够产生当前正确的一个。

尽管在您的示例中情况并非如此。在那里,您可能只拥有一个private static string token = ...,结果相同。

答案 4 :(得分:1)

使用环境变量进行配置是容器环境中的常见模式。这些变量预计会发生变化,因此使用Func<string>提取最新变量是有意义的。容器本身不需要了解任何有关配置存储的信息,也不需要了解如何进行或传播更改。

更改由协调器或主机传播到需要该特定设置的所有容器。这将允许不同组的容器使用不同的设置来工作,服务于不同的租户或..也许与不同的Github帐户一起工作?

尽管如此,容器应用程序仍然忽略了这一切。

AWS Lambda和Azure Functions基于容器,因此此模式很有意义。

为什么用Func代替字符串Property?

这是基于观点的。如果人们更喜欢函数式编程,那么传递和注入单一用途的函数要比传递具有单个属性或更差的多个可能不相关的属性的对象更好。

答案 5 :(得分:-1)

我的猜测是它正在尝试传达意图。

在执行方法时,您会更清楚地发现有可能引发错误,或者可以执行某些操作来更改该值,在这种情况下,这是环境配置。