日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

实现自己的.NET Core配置Provider之Yaml

發布時間:2023/12/4 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现自己的.NET Core配置Provider之Yaml 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

YAML是一種更適合人閱讀的文件格式,很多大型的項目像Ruby on Rails都選擇YAML作為配置文件的格式。如果項目的配置很少,用JSON或YAML沒有多大差別。看看rails項目中的配置文件,如果用JSON寫試試什么感受吧。

在《實現自己的.NET Core配置Provider之EF》中已經講過配置的執行流程,這里不再復述,直接動手。

YamlConfigurationProvider

Yaml是基于文件的,可以直接從FileConfigurationProvider繼承,在FileConfigurationProvider實現了監控文件變化并自動重新加載的功能。

internal class YamlConfigurationProvider : FileConfigurationProvider{ ? ?public YamlConfigurationProvider(FileConfigurationSource source) : base(source) ? ?{} ?

? ?public override void Load(Stream stream) ?
? ?
{ ?
? ? ?var parser = new YamlConfigurationFileParser();Data = parser.Parse(stream);} }

YamlConfigurationParser是解析Yaml文件的核心,后面會介紹。

YamlConfigurationSource

internal class YamlConfigurationSource : FileConfigurationSource{ ? ?public override IConfigurationProvider Build(IConfigurationBuilder builder) ? ?{EnsureDefaults(builder); ? ? ? ?return new YamlConfigurationProvider(this);} }

YamlConfigurationSource實現父類的Build方法,返回YamlConfigurationProvider。

AddYamlFile擴展方法

為添加Yaml配置源增加擴展方法。

public static class YamlConfigurationExtensions{ ?

?public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path) ? ?{ ? ?
? ? ?return AddYamlFile(builder, provider: null, path: path, optional: false, reloadOnChange: false);} ?
? ? ??public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path, bool optional)
? ?
{ ? ? ?
? ? ?? ?return AddYamlFile(builder, provider: null, path: path, optional: optional, reloadOnChange: false);} ?
? ? ?? ?public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange) ? ?{ ? ?
? ? ?? ?? ?return AddYamlFile(builder, provider: null, path: path, optional: optional, reloadOnChange: reloadOnChange);} ?
? ?
? ??public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange) ? ?{ ? ?
? ?? ? ?if (builder == null){ ? ? ? ?
? ?? ? ?? ?throw new ArgumentNullException(nameof(builder));} ? ? ?
? ?? ? ?if (string.IsNullOrEmpty(path)){ ? ? ? ? ? ?throw new ArgumentException(Resources.Error_InvalidFilePath, nameof(path));} ? ? ? ?return builder.AddYamlFile(s =>{s.FileProvider = provider;s.Path = path;s.Optional = optional;s.ReloadOnChange = reloadOnChange;s.ResolveFileProvider();});} ?
? ?? ?internal static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, Action<YamlConfigurationSource> configureSource) ? ?{ ? ? ?
? ?? ? ?var source = new YamlConfigurationSource();configureSource(source); ? ?
? ?? ? ?return builder.Add(source);} }

YamlConfigurationFileParser

解析Yaml是核心的功能,目前github有開源的C# Yaml項目:YamlDotNet和SharpYaml?。SharpYaml Fork自YamlDotNet,但做了不少改進并支持Yaml1.2,不過需要netstandard1.6+。YamlDotNet支持Yaml1.1,需要netstandard1.3+。我選擇的YamlSharp。

Yaml可表示三種類型的數據:Scalar(標量,如字符串、布爾值、整數等)、Sequence(序列,如數組)和Mapping(映射,如字典,鍵值對等)。

關于Yaml可以參考阮一峰老師的《YAML 語言教程》。

SharpYaml會把Yaml文件轉換為樹形結構,然后我們只需要把所有的葉子節點的路徑作為字典的鍵,將葉子節點的值作為字典的值存儲起來就可以了。

internal class YamlConfigurationFileParser{ ?

?private readonly IDictionary<string, string> _data = new SortedDictionary<string, string>(StringComparer.Ordinal); ?

?private readonly Stack<string> _context = new Stack<string>(); ? ?
private string _currentPath; ?
?public IDictionary<string, string> Parse(Stream input){_data.Clear();_context.Clear(); ? ? ? ?var yaml = new YamlStream();yaml.Load(new StreamReader(input)); ? ? ? ?if (yaml.Documents.Count > 0){ ? ? ? ? ? ?var rootNode = yaml.Documents[0].RootNode;VisitYamlNode("", rootNode);} ? ? ? ?return _data;} ?

?private void VisitYamlNode(string context, YamlNode node) ? ?{ ?
?? ? ?if (node is YamlScalarNode){VisitYamlScalarNode(context, (YamlScalarNode)node);} ? ? ?
?? ? ??else if (node is YamlMappingNode) ?
? ? ? ?
{VisitYamlMappingNode(context, (YamlMappingNode)node);} ? ? ?
?? ? ??else if (node is YamlSequenceNode) ? ? ? ?{VisitYamlSequenceNode(context, (YamlSequenceNode)node);}} ?

?private void VisitYamlScalarNode(string context, YamlScalarNode node) ? ?{EnterContext(context); ?
? ? ? ?if (_data.ContainsKey(_currentPath)){ ? ? ? ? ?
? ? ? ??throw new FormatException(string.Format(Resources.Error_KeyIsDuplicated, _currentPath));}_data[_currentPath] = node.Value;ExitContext();} ?

?private void VisitYamlMappingNode(string context, YamlMappingNode node) ? ?{EnterContext(context); ? ? ?
?foreach (var yamlNode in node.Children){context = ((YamlScalarNode)yamlNode.Key).Value;VisitYamlNode(context, yamlNode.Value);}ExitContext();} ?
?
??private void VisitYamlSequenceNode(string context, YamlSequenceNode node) ? ?{EnterContext(context); ? ? ?
?? ?for (int i = 0; i < node.Children.Count; i++){VisitYamlNode(i.ToString(), node.Children[i]);}ExitContext();} ?
?
??private void EnterContext(string context) ? ?{ ? ?
?? ?if (!string.IsNullOrEmpty(context)){_context.Push(context);}_currentPath = ConfigurationPath.Combine(_context.Reverse());} ?
?? ?
??private void ExitContext() ? ?
? ? ?{ ? ? ?
?? ? ?if (_context.Any()){_context.Pop();}_currentPath = ConfigurationPath.Combine(_context.Reverse());} }

最后

本項目已在github上開源,地址:https://github.com/chengxulvtu/Cxlt.Extensions.Configuration

在項目中使用可以執行下面的命令

Install-Package Cxlt.Extensions.Configuration.Yaml

dotnet add package Cxlt.Extensions.Configuration.Yaml

如果這篇文章對你有幫助或有什么問題,歡迎關注“chengxulvtu"公眾號。

相關文章:

  • 10分鐘就能學會的.NET Core配置

  • 實現自己的.NET Core配置Provider之EF

原文地址:http://www.cnblogs.com/nianming/p/7097338.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的实现自己的.NET Core配置Provider之Yaml的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。