Maison > Article > développement back-end > Tutoriel de configuration d'analyse d'ASP.NET Core - lecture des informations de configuration (recommandé)
Cet article présente principalement la première partie du didacticiel de configuration d'ASP.NET Core Lecture des informations sur la configuration Les amis intéressés peuvent se référer à
mentionné "Configuration" Deux mots, je pense que la plupart. NET penseront immédiatement à deux fichiers spéciaux dans leur esprit, à savoir app.config et web.config que nous connaissons tous trop bien. Au fil des années, nous avons été habitués à utiliser des informations de configuration structurées définies dans ces deux fichiers. . En ce qui concerne .NET Core, de nombreuses choses que nous tenons pour acquises ont changé, notamment la manière de définir les configurations. En général, le nouveau système de configuration est plus léger et offre une meilleure évolutivité. Sa principale caractéristique est qu'il prend en charge diverses sources de données. Nous pouvons utiliser la mémoire variable comme source de données de configuration, ou nous pouvons la configurer et la définir directement dans un fichier persistant ou même une base de données.
Étant donné que de nombreuses personnes n'ont jamais été exposées à ce système de configuration nouvellement conçu, afin d'en donner à chacun une compréhension sensorielle, nous allons d'abord l'expérimenter du point de vue de la programmation . L'API pour la configuration implique trois objets, qui sont Configuration, ConfigurationBuilder et ConfigurationProvider. Le modèle de configuration a l'interface correspondante pour les représenter. . La relation entre ces trois objets est très claire. L'objet Configuration transporte les informations de configuration utilisées dans le processus de programmation, et le ConfigurationProvider est le fournisseur de la source de données d'origine des informations de configuration. La communication entre les deux est complétée par le ConfigurationBuilder. qui utilise le ConfigurationProvider pour extraire les données source est converti en un objet Configuration.
1. Lire la configuration sous forme de paires clé-valeur
Bien que dans la plupart des cas, les informations de configuration aient une relation hiérarchique structurée dans leur ensemble, les éléments de configuration « atomiques » sont tous incarné sous la forme la plus simple de "paires clé-valeur", et les clés et les valeurs sont toutes deux des chaînes Ensuite, nous utiliserons un exemple simple pour montrer comment utiliser les clés. La configuration est lue sous la forme. de paires de valeurs. Nous créons une application console pour ASP.NET Core et ajoutons une dépendance sur le package NuGet « Microsoft.Extensions.Configuration » dans project.json comme suit. Le modèle de configuration est implémenté dans ce package.
{ ... "dependencies": { "Microsoft.Extensions.Configuration": "1.0.0-rc1-final" }, }
Supposons que notre application doive définir le format d'affichage de la date/heure via la configuration. À cette fin, nous définissons la classe DateTimeFormatSettings suivante. Ses quatre attributs incarnent DateTime Quatre formats d'affichage. pour les objets (date/heure longue et date/heure courte respectivement).
public class DateTimeFormatSettings { public string LongDatePattern { get; set; } public string LongTimePattern { get; set; } public string ShortDatePattern { get; set; } public string ShortTimePattern { get; set; } //其他成员 }
Nous espérons contrôler le format d'affichage de la date/heure reflété par les quatre propriétés de DateTimeFormatSettings via la configuration, nous définissons donc un constructeur pour cela. Comme le montre l'extrait de code suivant, le constructeur possède un paramètre de type interface IConfiguration, qui transporte formellement l'objet Configuration des informations de configuration associées. Nous appelons l'index de l'objet Configuration et spécifions la Clé de l'élément de configuration correspondant pour obtenir sa Valeur.
public class DateTimeFormatSettings { //其他成员 public DateTimeFormatSettings (IConfiguration configuration) { this.LongDatePattern = configuration["LongDatePattern"]; this.LongTimePattern = configuration["LongTimePattern"]; this.ShortDatePattern = configuration["ShortDatePattern"]; this.ShortTimePattern = configuration["ShortTimePattern"]; } }
Pour créer un objet DateTimeFormatSettings qui reflète la configuration actuelle, nous devons obtenir l'objet Configuration qui contient les informations de configuration pertinentes. Comme nous l'avons dit ci-dessus, l'objet Configuration est créé par ConfigurationBuilder et les informations de configuration d'origine sont lues via le ConfigurationProvider correspondant. La méthode de programmation correcte pour créer un objet Configuration consiste donc à créer d'abord un objet ConfigurationBuilder, puis à l'ajouter un ou plusieurs ConfigurationProvider. objets, et enfin utilisez ConfigurationBuilder pour créer l'objet Configuration dont nous avons besoin.
Selon le modèle de programmation ci-dessus, nous avons écrit le programme suivant dans une application console. Nous avons créé un objet de type ConfigurationBuilder et le ConfigurationProvider ajouté en appelant sa méthode Add est un objet de type MemoryConfigurationProvider. Comme son nom l'indique, MemoryConfigurationProvider utilise des objets en mémoire pour fournir des informations de configuration d'origine. Plus précisément, ces informations de configuration d'origine sont stockées dans une collection dont le type d'élément est KeyValuePair708d620c35cc3f2d1dd0b997d136c07a. Nous appelons enfin la méthode Build de ConfigurationBuilder pour obtenir la Configuration requise pour créer un objet DateTimeFormatSettings.
public class Program { public static void Main(string[] args) { Dictionary<string, string> source = new Dictionary<string, string> { ["LongDatePattern"] = "dddd, MMMM d, yyyy", ["LongTimePattern"] = "h:mm:ss tt", ["ShortDatePattern"] = "M/d/yyyy", ["ShortTimePattern"] = "h:mm tt" }; IConfiguration configuration = new ConfigurationBuilder() .Add(new MemoryConfigurationProvider(source)) .Build(); DateTimeFormatSettings settings = new DateTimeFormatSettings(configuration); Console.WriteLine("{0,-16}: {1}", "LongDatePattern", settings.LongDatePattern); Console.WriteLine("{0,-16}: {1}", "LongTimePattern", settings.LongTimePattern); Console.WriteLine("{0,-16}: {1}", "ShortDatePattern", settings.ShortDatePattern); Console.WriteLine("{0,-16}: {1}", "ShortTimePattern", settings.ShortTimePattern); } }
为了验证根据配置创建的DateTimeFormatSettings对象与配置原始数据之间的关系,我们将它的四个属性输出于控制台上。当这个程序执行之后将在控制台上产生如下所示的输出,可以看出它正是我们提供的配置的真实反映。
LongDatePattern : dddd, MMMM d, yyyy
LongTimePattern : h:mm:ss tt
ShortDatePattern: M/d/yyyy
ShortTimePattern: h:mm tt
二、 读取结构化的配置
真实项目中涉及的配置大都具有一个结构化的层次结构,所以在配置模型中的Configuration对象同样具有这样的结构。结构化的配置具有一个树形层次结构,而一个Configuration对象表示的是组成这棵配置树的某个节点,这棵配置树则可以通过作为根节点的Configuration对象来体现。体现为键值对的原子配置项一般至存在于作为叶子节点的Configuration对象中,非叶子节点的Configuration包含一组子节点,而每个子节点同样是一个Configuration对象。
接下来我们同样以实例的方式来演示如何定义并读取具有层次化结构的配置。我们依然沿用上一节的应用场景,现在我们不仅仅需要设置日期/时间的格式,还需要设置其他数据类型的格式,比如表示货币的Decimal类型。为此我们定义了如下一个CurrencyDecimalFormatSettings类,它的属性Digits和Symbol分别表示小数位数和货币符号,一个CurrencyDecimalFormatSettings对象依然是利用一个表示配置的Configuration对象来创建的。
{ public int Digits { get; set; } public string Symbol { get; set; } public CurrencyDecimalFormatSettings(IConfiguration configuration) { this.Digits = int.Parse(configuration["Digits"]); this.Symbol = configuration["Symbol"]; } }
我们定义了另一个名为FormatSettings的类型来表示针对不同数据类型的格式设置。如下面的代码片段所示,它的两个属性DateTime和CurrencyDecimal分别表示针对日期/时间和货币数字的格式设置。FormatSettings依然具有一个参数类型为IConfiguration接口的构造函数,它的两个属性均在此构造函数中被初始化。值得注意的是初始化这两个属性采用的是当前Configuration的“子配置节”,通过指定配置节名称调用GetSection方法获得。
public class FormatSettings { public DateTimeFormatSettings DateTime { get; set; } public CurrencyDecimalFormatSettings CurrencyDecimal { get; set; } public FormatSettings(IConfiguration configuration) { this.DateTime = new DateTimeFormatSettings(configuration.GetSection("DateTime")); this.CurrencyDecimal = new CurrencyDecimalFormatSettings(configuration.GetSection("CurrencyDecimal")); } }
在我们上面演示的实例中,我们通过以一个MemoryConfigurationProvider对象来提供原始的配置信息。由于承载原始配置信息的是一个元素类型为KeyValuePair708d620c35cc3f2d1dd0b997d136c07a的集合,所以原始配置在物理存储上并不具有树形化的层次结构,那么它如何能够最终提供一个结构化的Configuration对象呢?其实很简单,虽然MemoryConfigurationProvider对象只能将配置信息存储为简单的“数据字典”,但是如果将Configuration对象在配置树中体现的路径作为Key,这个数据字典在逻辑上实际上就具有了一棵树的结构。实际上MemoryConfigurationProvider就是这么做的,这体现在我们如下所示的程序之中。
class Program { static void Main(string[] args) { Dictionary<string, string> source = new Dictionary<string, string> { ["Format:DateTime:LongDatePattern"] = "dddd, MMMM d, yyyy", ["Format:DateTime:LongTimePattern"] = "h:mm:ss tt", ["Format:DateTime:ShortDatePattern"] = "M/d/yyyy", ["Format:DateTime:ShortTimePattern"] = "h:mm tt", ["Format:CurrencyDecimal:Digits"] = "2", ["Format:CurrencyDecimal:Symbol"] = "$", }; IConfiguration configuration = new ConfigurationBuilder() .Add(new MemoryConfigurationProvider(source)) .Build(); FormatSettings settings = new FormatSettings(configuration.GetSection("Format")); Console.WriteLine("DateTime:"); Console.WriteLine("\t{0,-16}: {1}", "LongDatePattern", settings.DateTime.LongDatePattern); Console.WriteLine("\t{0,-16}: {1}", "LongTimePattern", settings.DateTime.LongTimePattern); Console.WriteLine("\t{0,-16}: {1}", "ShortDatePattern", settings.DateTime.ShortDatePattern); Console.WriteLine("\t{0,-16}: {1}\n", "ShortTimePattern", settings.DateTime.ShortTimePattern); Console.WriteLine("CurrencyDecimal:"); Console.WriteLine("\t{0,-16}: {1}", "Digits", settings.CurrencyDecimal.Digits); Console.WriteLine("\t{0,-16}: {1}", "Symbol", settings.CurrencyDecimal.Symbol); } }
如上面的代码片段所示,创建MemoryConfigurationProvider对象采用的字典对象包含6个基本的配置项,为了让它们在逻辑上具有一个树形化层次结构,所以的Key实际上体现了每个配置项所在配置节在配置树中的路径,路径采用冒号(“:”)进行分割。改程序执行之后会在控制台上呈现如下所示的输出结果。
DateTime: LongDatePattern : dddd, MMMM d, yyyy LongTimePattern : h:mm:ss tt ShortDatePattern: M/d/yyyy ShortTimePattern: h:mm tt CurrencyDecimal: Digits : 2 Symbol : $
三、将结构化配置直接绑定为对象
在真正的项目开发过程中,我们都不会直接使用直接读取的配置,而都倾向于像我们演示的两个实例一样通过创建相应的类型(比如DateTimeFormatSettings、CurrencyDecimalSettings和FormatSettings)来定义一组相关的配置选项(Option),我们将定义配置选项(Option)的这些类型称为Option类型。在上面演示的实例中,为了创建这些封装配置的对象,我们都是采用手工读取配置的形式,如果定义的配置项太多的话,逐条读取配置项其实是一项非常繁琐的工作。
对于一个对象来说,如果我们将它的属性视为它的子节点,一个对象同样具有类似于Configuration对象的树形层次化结构。如果我们根据某个Option类型的结构来定义配置,或者反过来根据配置的结构来定义这个Option类型,那么Option类型的属性成员将与某个配置节具有一一对应的关系,那么原则上我们可以自动将配置信息绑定为一个具体的Option对象。
ASP.NET Core针对配置的Option模型(OptionModel)帮助我们实现了从配置到Option对象之间的绑定,接下来我们就对此做一个简单的演示。Option模型实现在“Microsoft.Extensions.OptionModel”这个NuGet包中,除此之外,我们需要采用依赖注入的方式来使用Option模型,所以我们需要按照如下的方式为应用添加针对相应的依赖。
{ ... "dependencies": { "Microsoft.Extensions.OptionsModel" : "1.0.0-rc1-final", "Microsoft.Extensions.DependencyInjection" : "1.0.0-rc1-final" }, }
借助于Option模型的自动绑定机制,我们无需再手工地读取配置信息,所以我们将FormatSettings、DateTimeFormatSettings和CurrencyDecimalSettings的构造函数删除,只保留其属性成员。在作为程序入口的Main方法中,我们采用如下的方式创建这个表示格式设置的FormatSettings对象。
class Program { static void Main(string[] args) { Dictionary<string, string> source = new Dictionary<string, string> { ["Format:DateTime:LongDatePattern"] = "dddd, MMMM d, yyyy", ["Format:DateTime:LongTimePattern"] = "h:mm:ss tt", ["Format:DateTime:ShortDatePattern"] = "M/d/yyyy", ["Format:DateTime:ShortTimePattern"] = "h:mm tt", ["Format:CurrencyDecimal:Digits"] = "2", ["Format:CurrencyDecimal:Symbol"] = "$", }; IConfiguration configuration = new ConfigurationBuilder() .Add(new MemoryConfigurationProvider(source)) .Build() .GetSection("Format")); IOptions<FormatSettings> optionsAccessor = new ServiceCollection() .AddOptions() .Configure<FormatSettings>(configuration) .BuildServiceProvider() .GetService<IOptions<FormatSettings>>(); FormatSettings settings = optionsAccessor.Value; Console.WriteLine("DateTime:"); Console.WriteLine("\t{0,-16}: {1}", "LongDatePattern",settings.DateTime.LongDatePattern); Console.WriteLine("\t{0,-16}: {1}", "LongTimePattern",settings.DateTime.LongTimePattern); Console.WriteLine("\t{0,-16}: {1}", "ShortDatePattern",settings.DateTime.ShortDatePattern); Console.WriteLine("\t{0,-16}: {1}\n", "ShortTimePattern",settings.DateTime.ShortTimePattern); Console.WriteLine("CurrencyDecimal:"); Console.WriteLine("\t{0,-16}: {1}", "Digits",settings.CurrencyDecimal.Digits); Console.WriteLine("\t{0,-16}: {1}", "Symbol",settings.CurrencyDecimal.Symbol); } }
如上面的代码片段所示,我们创建一个ServiceCollection对象并调用扩展方法AddOptions注册于针对Option模型的服务。接下来我们调用Configure方法将FormatSettings这个Option类型与对应的Configuration对象进行映射。我们最后利用这个ServiceCollection对象生成一个ServiceProvider,并调用其GetService方法得到一个类型为IOptionsb7508df415eea39e792050f586bf7677的对象,后者的Value属性返回的就是绑定了相关配置的FormatSettings对象。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!