<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>




      官方文檔存在的問題

      可能由于 Apollo 配置中心的客戶端源碼一直處于更新中,導(dǎo)致其相關(guān)文檔有些跟不上節(jié)奏,部分文檔寫的不規(guī)范,很容易給做對接的新手朋友造成誤導(dǎo)。

      比如,我在參考如下兩個文檔使用傳統(tǒng) .NET 客戶端做接入的時候就發(fā)現(xiàn)了些問題。

      * ctripcorp/apollo - .Net客戶端使用指南
      <https://github.com/ctripcorp/apollo/wiki/.Net%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97>
      * ctripcorp/apollo.net - .Net客戶端之與 System.Configuration.ConfigurationManager
      集成
      <https://github.com/ctripcorp/apollo.net/blob/dotnet-core/Apollo.ConfigurationManager/README.md>
      1.兩個文檔關(guān)于標(biāo)識應(yīng)用身份的AppId的配置節(jié)點不一致。



      2.第二個文檔關(guān)于應(yīng)用配置發(fā)布環(huán)境的Environment配置節(jié)點的描述出現(xiàn)明顯錯誤。


      當(dāng)然,這些問題隨時都有可能被修復(fù)。若您看到文檔內(nèi)容與本文描述不符,請以官方文檔為準(zhǔn)。

      傳統(tǒng) .NET 項目快速接入

      快速進入正題。

      安裝依賴包

      在您項目的基礎(chǔ)設(shè)施層,通過 NuGet 包管理器或使用如下命令添加傳統(tǒng) .NET 項目使用的客戶端:
      Install-Package Com.Ctrip.Framework.Apollo.ConfigurationManager -Version 2.0.3
      從上面的包名能看出什么?我這里選裝的是2.0.3的版本。還有,這應(yīng)該是一個 Javaer 起的名字。

      配置應(yīng)用標(biāo)識 & 服務(wù)地址

      在您的啟動項目中,打開App.config或Web.config配置文件,在<appSettings>節(jié)點中增加如下節(jié)點:
      <!-- Change to the actual app id --> <add key="Apollo.AppID" value="R01001" />
      <add key="Apollo.MetaServer" value="http://localhost:8080" />
      若您部署了多套 Config Service,支持多環(huán)境,請參考如下配置:
      <!-- Change to the actual app id --> <add key="Apollo.AppID" value="R01001" />
      <!-- Should change the apollo config service url for each environment --> <add
      key="Apollo.Env" value="DEV" /> <add key="Apollo.DEV.Meta"
      value="http://localhost:8080"/> <add key="Apollo.FAT.Meta"
      value="http://localhost:8081"/> <add key="Apollo.UAT.Meta"
      value="http://localhost:8082"/> <add key="Apollo.PRO.Meta"
      value="http://localhost:8083"/>
      配置完成后,就可以準(zhǔn)備在我們項目中使用 Apollo 客戶端了。

      二次封裝代碼

      我們習(xí)慣在項目中使用第三方庫的時候封裝一層,這種封裝是淺層的,一般都是在項目的基礎(chǔ)設(shè)施層來做,這樣其他層使用就不需要再次引入依賴包。

      不說了,直接上代碼吧。

      代碼結(jié)構(gòu)大致如下:
      ├─MyCompany.MyProject.Infrastructure # 項目基礎(chǔ)設(shè)施層 │ │ │ └─Configuration │
      ApolloConfiguration.cs # Apollo 分布式配置項讀取實現(xiàn) │ ConfigurationChangeEventArgs.cs #
      配置更改回調(diào)事件參數(shù) │ IConfiguration.cs # 配置抽象接口,可基于此接口實現(xiàn)本地配置讀取
      IConfiguration
      using System; using System.Configuration; namespace
      MyCompany.MyProject.Infrastructure { /// <summary> /// 配置抽象接口。 /// </summary>
      public interface IConfiguration { /// <summary> /// 配置更改回調(diào)事件。 /// </summary>
      event EventHandler<ConfigurationChangeEventArgs> ConfigChanged; /// <summary>
      /// 獲取配置項。 /// </summary> /// <param name="key">鍵</param> /// <param
      name="namespaces">命名空間集合</param> /// <returns></returns> string GetValue(string
      key, params string[] namespaces); /// <summary> /// 獲取配置項。 /// </summary> ///
      <typeparam name="TValue">值類型</typeparam> /// <param name="key">鍵</param> ///
      <param name="namespaces">命名空間集合</param> /// <returns></returns> TValue
      GetValue<TValue>(string key, params string[] namespaces); /// <summary> ///
      獲取配置項,如果值為 <see cref="null"/> 則取參數(shù) <see cref="defaultValue"/> 值。 /// </summary>
      /// <param name="key">鍵</param> /// <param name="defaultValue">默認值</param> ///
      <param name="namespaces">命名空間集合</param> /// <returns></returns> string
      GetDefaultValue(string key, string defaultValue, params string[] namespaces);
      /// <summary> /// 獲取配置項,如果值為 <see cref="null"/> 則取參數(shù) <see cref="defaultValue"/>
      值。 /// </summary> /// <typeparam name="TValue">值類型</typeparam> /// <param
      name="key">鍵</param> /// <param name="defaultValue">默認值</param> /// <param
      name="namespaces">命名空間集合</param> /// <returns></returns> TValue
      GetDefaultValue<TValue>(string key, TValue defaultValue, params string[]
      namespaces); } }
      ConfigurationChangeEventArgs
      using Com.Ctrip.Framework.Apollo.Model; using System.Collections.Generic;
      namespace MyCompany.MyProject.Infrastructure { public class
      ConfigurationChangeEventArgs { public IEnumerable<string> ChangedKeys =>
      Changes.Keys; public bool IsChanged(string key) => Changes.ContainsKey(key);
      public string Namespace { get; } public IReadOnlyDictionary<string,
      ConfigChange> Changes { get; } public ConfigurationChangeEventArgs(string
      namespaceName, IReadOnlyDictionary<string, ConfigChange> changes) { Namespace =
      namespaceName; Changes = changes; } public ConfigChange GetChange(string key) {
      Changes.TryGetValue(key, out var change); return change; } } }
      ApolloConfiguration
      using System; using System.Configuration; using System.Globalization; using
      Com.Ctrip.Framework.Apollo; using Com.Ctrip.Framework.Apollo.Model; namespace
      MyCompany.MyProject.Infrastructure { public class ApolloConfiguration :
      IConfiguration { private readonly string _defaultValue = null; public event
      EventHandler<ConfigurationChangeEventArgs> ConfigChanged; private IConfig
      GetConfig(params string[] namespaces) { var config = namespaces == null ||
      namespaces.Length == 0 ?
      ApolloConfigurationManager.GetAppConfig().GetAwaiter().GetResult() :
      ApolloConfigurationManager.GetConfig(namespaces).GetAwaiter().GetResult();
      config.ConfigChanged += (object sender, ConfigChangeEventArgs args) => {
      ConfigChanged(sender, new ConfigurationChangeEventArgs(args.Namespace,
      args.Changes)); }; return config; } public string GetValue(string key, params
      string[] namespaces) { key = key ?? throw new
      ArgumentNullException(nameof(key)); var config = GetConfig(namespaces); return
      config.GetProperty(key, _defaultValue); } public TValue GetValue<TValue>(string
      key, params string[] namespaces) { var value = GetValue(key, namespaces);
      return value == null ? default(TValue) : (TValue)Convert.ChangeType(value,
      typeof(TValue), CultureInfo.InvariantCulture); } public string
      GetDefaultValue(string key, string defaultValue, params string[] namespaces) {
      key = key ?? throw new ArgumentNullException(nameof(key)); var config =
      GetConfig(namespaces); return config.GetProperty(key, defaultValue); } public
      TValue GetDefaultValue<TValue>(string key, TValue defaultValue, params string[]
      namespaces) { var value = GetDefaultValue(key, defaultValue, namespaces);
      return value == null ? default(TValue) : (TValue)Convert.ChangeType(value,
      typeof(TValue), CultureInfo.InvariantCulture); } } }
      正確使用姿勢

      在使用之前需要先把ApolloConfiguration注冊到應(yīng)用容器中,請參考如下代碼:
      // 這里我們項目使用的 DI 框架是`Autofac`,按需修改吧,記得將實例注冊成單例模式。 public class
      DependencyRegistrar : IDependencyRegistrar { public void
      Register(ContainerBuilder builder, ITypeFinder typeFinder) {
      builder.RegisterType<ApolloConfiguration>() .As<IConfiguration>()
      .Named<IConfiguration>("configuration") .SingleInstance(); ... } public int
      Order { get { return 1; } } }
      接下來就可以在項目中使用了,請參考如下代碼:
      public class UserController : BaseController { private readonly IConfiguration
      _configuration; public UserController(IConfiguration configuration) {
      _configuration = configuration; } public ActionResult Add(AddUserInput model) {
      if (ModelState.IsValid) { // 從 Apollo 分布式配置中心 項目`R01001` 默認命名空間`application`下
      讀取配置項。 model.Password = _configuration.GetValue("DefaultUserPassword"); ... }
      ... } }

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          亲子乱一区二区三区 | avav片在线看 | 做爰高潮全过程免费 | 伊人高清在线 | xxxxwwww视频 | 国产成人在线视频 | 午夜电影院理论片做爰 | 国产成人精品一级毛片在码A片 | 国产黄色一级 | 天天日日 |