.NET Core 2.x中使用Named Options处理多个强类型配置实例
來源: Using multiple instances of strongly-typed settings with named options in .NET Core 2.x
作者: Andrew Lock
譯者: Lamond Lu
.NET Core從1.0版本開始,就已經開始使用Options模式綁定強類型配置對象。從那時起到現在,這個特性已經獲得了更多的功能。例如在.NET Core 1.1中引入的IOptionsSnapshot類。使用這個類的好處是,當你的配置文件(例如: appsetting.json)發生變化時,它可以幫助我們自動刷新我們的強類型配置對象。
本篇博客中,我們將討論在依賴注入容器中注冊強類型配置的多個實例的幾種方式。我將特別說明如何使用Named Options方式來完成注入。
使用強類型配置
Options模式將POCO對象和IConfiguration對象綁定,從而實現強類型配置。因為這一過程我已經在之前一篇博文中介紹過,所以這里我就簡述一下。
我們可以將強類型配置對象和配置綁定起來,并注入到你的服務中。
你可以在Startup類的ConfigureServices中使用Configure將強類型配置對象和配置中的一個節點綁定起來。
以上代碼中,Configure方法將你的配置和SlackApiSettings對象綁定了起來。除了以上方式,Configure方法還提供了一個參數為Action的重載,所以你來可以使用如下的方式綁定配置。
你可以通過在服務中注入IOptions對象來訪問配置好的SlackApiSettings對象。
你可以使用IOptions.Value屬性,獲取到配置好的強類型對象。
除了以上方式,你還可以注入一個IOptionsSnapshot接口對象。
使用IOptionsSnapshot處理配置變化
到目前為止,我所展示的例子都是最典型的用法。但是當我們使用IOption來讀取強類型配置時,這意味著你的配置在程序生命周期中是不變的。即配置對象只會計算和綁定一次。假如你在程序運行過程中,更改了appSettings.json文件,程序讀取配置時,依然會得到程序啟動時的配置對象,而非你修改過之后的配置對象。
對我個人而言,對于大部分場景,使用IOption已經能夠解決所有問題。但是如果程序確實需要支持重新加載配置,我們還可以使用ASP.NET Core中的IOptionsSnapshot。IOptionsSnapshot和IOptions使用方法一樣,因此你無需在應用程序中執行任何額外的操作。你只需要使用IOptionsSnapshot.Value屬性讀取配置對象即可。
使用以上方式,如果你在程序啟動后,修改了appSettings.json文件,IOptionsSnapshot會在下一次請求時,更新配置值,你就能獲取到新的配置值了。這里需要注意的是配置值的生命周期是Scoped, 即在一次請求中,讀取到的配置值都是一樣的。
注意: 并不是所有的配置提供器都支持配置重新加載。文件類型的配置器都沒有問題,但是環境變量配置器就不可以。
重新加載配置在某些情況下可能很有用,但IOptionsSnapshot還有另一個技巧 - 命名選項(Named Options)。 我們很快就會介紹它們,但首先我們將看一下你可能偶爾遇到的問題,您需要擁有多個設置對象實例。
使用一個強類型配置對象的多個實例
IOption的典型用例就是針對細粒度的配置。配置系統讓你很容易的為特定服務注入小的,集中的POCO對象。但是如果你需要配置多個具有相同屬性的配置對象時,應該怎么做的?例如,為了將消息發送到Slack, 你需要一個Webhook Url和一個DisplayName. 當你調用SendNotification(message)時,SlackNotificationService會使用這些配置來向指定的Slack Channel中發送消息。
如果你想更新SlackNotificationService以允許你向多個頻道發送消息,該怎么辦?
這里我已經為創建了向不同的頻道發送消息的方法。但是問題是,我該如何為每個頻道配置其對應的Webhook Url和DisplayName。
為了提供一些思路,這里我們假設我們的配置文件結構是這樣的。
為了在SlackNotificationService中讀取到響應的配置,這里有3種可行的方案。
1. 創建父類配置對象
第一種方式就是擴展SlackApiSettings類,在其中包含各個頻道的配置屬性。
這里我創建了一個內嵌類ChannelSettings, 并在SlackApiSettings類中添加了針對3個Slack Channel的配置。這個新的配置類,正確反映了appSettings.json文件中的配置結構。
在SlackNotificationService中,我們還是和之前一樣注入的單個配置類對象
這種配置方式的優點是易于理解,我們為每個Slack Channel配置了獨立的強類型配置。缺點是如果要支持新的Slack Channel, 你每次都需要修改SlackApiSettings類。
2. 為每個Channel配置創建單獨的配置類
另外一種方法是我們可以獨立配置每個Slack Channel。我們分開配置不同的Slack Channel, 并把他們注入到SlackNotificationService服務中。
例如,我們將ChannelSettings類變成一個抽象類
然后每一個Slack Channel的配置類繼承ChannelSettings類。
為了配置不同的Slack Channel, 我們需要在程序啟動時分別綁定不同的配置節點。
由于不同的Slack Channel擁有不同的配置,所以我們需要分開將他們注入到SlackNotificationService中。
這種方式的好處是當你需要添加新的Slack Channel配置時,你不需要去修改之前定義的配置類結構,你只需要添加一個針對新Slack Channel的配置類。但是它也讓事情更加復雜了,你不僅需要為每個新的Slack Channel配置類綁定配置的節點, 還需要修改SlackNotificationService的構造函數添加對新Slack Channel配置類的依賴。
3. 使用Named Options
第三種方案就是本文的主題Named Options。Named Options翻譯過來就是命名配置,和它的字面意思一樣,我們可以使用它為每個強類型配置對象起一個唯一的名稱,并在使用時通過指定唯一名稱來獲取所需的強類型配置對象。
使用Named Options, 你可以擁有同一個強類型配置類的不同實例,并獨立配置他們。這意味著,我們可以繼續使用本文開頭所定義的SlackApiSettings類。
我們使用的Configure的2個參數的重載方法,其中第一個參數指定了一個唯一名稱,第二個參數指定了配置文件中對應的節點名稱。
為了使用這些命名配置(Named Options), 我們需要在SlackNotificationService類的構造函數中注入IOptionSnapshot對象,而不是我們之前使用的IOption對象。IOptionsSnapshot.Get(name)方法允許我們通過傳入唯一名稱,獲取對應的強類型配置對象。
這種方式最大的好處是,當添加新的Slack Channel時,你不需要添加任何新的配置類,你只需要針對新的Slack Channel配置一個新的SlackApiSetting對象即可。缺點是從SlackNotificationService的構造函數上,你已經不知道它對應的配置節點是哪個了。
總結
在本篇博客中,我們介紹了如何在ASP.NET Core中使用強類型配置。然后我們討論了如何在ASP.NET Core的依賴注入容器中添加強類型配置對象的多個實例。這里我們講解了使用3種不同的方式
創建父類配置對象
為每個Channel配置創建單獨的配置類
使用Named Options
原文地址:https://www.cnblogs.com/lwqlun/p/10133041.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的.NET Core 2.x中使用Named Options处理多个强类型配置实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 领域驱动设计,让程序员心中有码(三)
- 下一篇: 撒花!中文翻译仓库链接已加入 ML.NE