zoukankan      html  css  js  c++  java
  • ASP.NET Core快速入门(第2章:配置管理)--学习笔记

    课程链接:http://video.jessetalk.cn/course/explore

    良心课程,大家一起来学习哈!

    任务9:配置介绍

    • 命令行配置
    • Json文件配置
    • 从配置文件文本到c#对象实例的映射 - Options 与 Bind
    • 配置文件热更新
    • 框架设计:Configuration

    任务10:命令行配置

    新建项目CommandLineSample--控制台应用(.NET Core)

    管理NuGet程序包--下载microsoft.aspnetcore.all

    传入参数

    using System;
    using Microsoft.Extensions.Configuration;
    
    namespace CommandLineSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                var builder = new ConfigurationBuilder()
                    .AddCommandLine(args);
    
                var configuration = builder.Build();
    
                Console.WriteLine($"name: {configuration ["name"]}");
                Console.WriteLine($"age: {configuration["age"]}");
    
                Console.ReadLine();
            }
        }
    }
    
    

    项目右键--调试--输入参数:name=mingsonzheng age=18

    启动项目

    默认参数

    using System;
    using System.Collections.Generic;
    using Microsoft.Extensions.Configuration;
    
    namespace CommandLineSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                var settings = new Dictionary<string, string>
                {
                    {"name", "mingsonzheng" },
                    {"age", "18" }
                };
    
                var builder = new ConfigurationBuilder()
                    .AddInMemoryCollection(settings)
                    .AddCommandLine(args);
    
                var configuration = builder.Build();
    
                Console.WriteLine($"name: {configuration ["name"]}");
                Console.WriteLine($"age: {configuration["age"]}");
    
                Console.ReadLine();
            }
        }
    }
    
    

    清空应用程序参数

    启动项目

    通过PowerShell运行程序,默认参数与传入参数对比

    PS D:jessetalkCommandLineSampleCommandLineSampleinDebug
    etcoreapp2.1> dotnet CommandLineSample.dll
    name: mingsonzheng
    age: 18
    
    PS D:jessetalkCommandLineSampleCommandLineSampleinDebug
    etcoreapp2.1> dotnet CommandLineSample.dll name=jim age=22
    name: jim
    age: 22
    

    任务11:Json文件配置

    新建项目JsonComfigSample--控制台应用(.NET Core)

    管理NuGet程序包--下载microsoft.aspnetcore.all

    添加Json文件:项目右键--添加新建项class.json

    {
      "ClassNo": "1",
      "ClassDesc": "ASP.NET Core 101",
    
      "Students": [
        {
          "name": "mingsonzheng",
          "age": "18"
        },
        {
          "name": "jim",
          "age": "28"
        },
        {
          "name": "tom",
          "age": "38"
        }
      ]
    }
    

    由于class.json不在binDebug目录下,所以默认不会被编译,文件右键属性,修改为始终复制

    using System;
    using Microsoft.Extensions.Configuration;
    
    namespace JsonComfigSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                var builder = new ConfigurationBuilder()
                    .AddJsonFile("class.json");
    
                Console.ReadLine();
            }
        }
    }
    
    

    启动项目,可以看到class.json被复制到binDebug目录,这样dll就可以读取到class.json文件

    读取json文件

    using System;
    using Microsoft.Extensions.Configuration;
    
    namespace JsonComfigSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                var builder = new ConfigurationBuilder()
                    .AddJsonFile("class.json");
    
                // 调用Build之前请确保拷贝的class.json文件没有格式错误
                var configuration = builder.Build();
    
                Console.WriteLine($"ClassNo: { configuration["ClassNo"]}");
                Console.WriteLine($"ClassDesc: { configuration["ClassDesc"]}");
    
                Console.WriteLine("Students");
    
                Console.Write(configuration["Students:0:name"]);
                Console.WriteLine(configuration["Students:0:age"]);
    
                Console.Write(configuration["Students:1:name"]);
                Console.WriteLine(configuration["Students:1:age"]);
    
                Console.Write(configuration["Students:2:name"]);
                Console.WriteLine(configuration["Students:2:age"]);
    
                Console.ReadLine();
            }
        }
    }
    
    

    启动项目

    任务12:Bind读取配置到C#实例

    新建ASP.NET Core Web 应用程序OptionsBindSample,直接选择 空,确定

    在Startup.cs中通过依赖注入添加configuration

    public IConfiguration Configuration { get; set; }
    
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    

    项目右键,新建项,添加一个类Class.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace OptionsBindSample
    {
        public class Class
        {
            public int ClassNo { get; set; }
    
            public string ClassDesc { get; set; }
    
            public List<Student> Students { get; set; }
    
        }
    
        public class Student
        {
            public string Name { get; set; }
    
            public string Age { get; set; }
        }
    }
    
    

    项目右键,新建项,添加一个Json文件appsettings.json

    为什么取名appsettings.json呢?

    因为Program.cs中的CreateDefaultBuilder默认读取一个名为appsettings.json的Json文件并把它的内容添加到配置文件

    拷贝前面的内容到appsettings.json

    {
      "ClassNo": "1",
      "ClassDesc": "ASP.NET Core 101",
    
      "Students": [
          {
            "name": "mingsonzheng",
            "age": "18"
          },
          {
            "name": "jim",
            "age": "28"
          },
          {
            "name": "tom",
            "age": "38"
          }
      ]
    }
    
    

    在Startup.cs中通过Bind读取配置

    app.Run(async (context) =>
    {
        var myClass = new Class();
        Configuration.Bind(myClass);// 实现配置文件信息与对象的映射
    
        await context.Response.WriteAsync($"ClassNo: { myClass.ClassNo}");
        await context.Response.WriteAsync($"ClassDesc: { myClass.ClassDesc}");
        await context.Response.WriteAsync($" {myClass.Students.Count } Students");
    });
    

    完整Startup.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace OptionsBindSample
    {
        public class Startup
        {
    
            public IConfiguration Configuration { get; set; }
    
            // 通过依赖注入添加configuration
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
            public void ConfigureServices(IServiceCollection services)
            {
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.Run(async (context) =>
                {
                    var myClass = new Class();
                    Configuration.Bind(myClass);// Bind读取配置
    
                    await context.Response.WriteAsync($"ClassNo: { myClass.ClassNo}");
                    await context.Response.WriteAsync($"ClassDesc: { myClass.ClassDesc}");
                    await context.Response.WriteAsync($" {myClass.Students.Count } Students");
                });
            }
        }
    }
    
    

    启动项目

    任务13:在Core Mvc中使用Options

    在项目OptionsBindSample新建三个文件夹目录如下

    在Controllers文件夹右键,添加一个控制器,默认,HomeController

    在Home文件夹右键,添加一个视图,默认,Index

    在Startup.cs中注释掉这一段代码,不然会把整个管道提交,只输出这一段

    //app.Run(async (context) =>
    //{
    //    var myClass = new Class();
    //    Configuration.Bind(myClass);// Bind读取配置
    
    //    await context.Response.WriteAsync($"ClassNo: { myClass.ClassNo}");
    //    await context.Response.WriteAsync($"ClassDesc: { myClass.ClassDesc}");
    //    await context.Response.WriteAsync($" {myClass.Students.Count } Students");
    //});
    

    依赖注入配置添加MVC

    services.AddMvc();
    

    使用默认路由

    app.UseMvcWithDefaultRoute();
    

    HomeController中通过IOptions方式依赖注入

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Options;
    
    namespace OptionsBindSample.Controllers
    {
        public class HomeController : Controller
        {
            private readonly Class _myClass;
    
            // 通过IOptions方式依赖注入
            public HomeController(IOptions<Class> classAccesser)
            {
                _myClass = classAccesser.Value;
            }
    
            public IActionResult Index()
            {
                return View(_myClass);
            }
        }
    }
    

    在Index中定义模型,输出

    @model OptionsBindSample.Class
    @{
        ViewData["Title"] = "Index";
    }
    
    <h2>Index</h2>
    <h4>Class No: @Model.ClassNo</h4>
    <h4>Class Desc: @Model.ClassDesc</h4>
    <h3>
        Students:
    </h3>
    <div>
        @foreach (var student in Model.Students)
        {
            <span>Name: @student.Name</span>
            <span>Age: @student.Age</span>
        }
    </div>
    
    

    注册Class,可以通过Configuration读取到option

    services.Configure<Class>(Configuration);
    

    Startup.cs完整代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace OptionsBindSample
    {
        public class Startup
        {
    
            public IConfiguration Configuration { get; set; }
    
            // 通过依赖注入添加configuration
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
            public void ConfigureServices(IServiceCollection services)
            {
                // 注册Class,可以通过Configuration读取到option
                services.Configure<Class>(Configuration);
                // 依赖注入配置添加MVC
                services.AddMvc();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                // 使用默认路由
                app.UseMvcWithDefaultRoute();
    
                //app.Run(async (context) =>
                //{
                //    var myClass = new Class();
                //    Configuration.Bind(myClass);// Bind读取配置
    
                //    await context.Response.WriteAsync($"ClassNo: { myClass.ClassNo}");
                //    await context.Response.WriteAsync($"ClassDesc: { myClass.ClassDesc}");
                //    await context.Response.WriteAsync($" {myClass.Students.Count } Students");
                //});
            }
        }
    }
    
    

    启动项目

    如果仅仅在视图中使用options的话,HomeController的代码有点多余,可以直接在视图中注入

    Index

    @using Microsoft.Extensions.Options;
    @inject IOptions<OptionsBindSample.Class> ClassAccesser
    @{
        ViewData["Title"] = "Index";
    }
    
    <h2>Index</h2>
    <h4>Class No: @ClassAccesser.Value.ClassNo</h4>
    <h4>Class Desc: @ClassAccesser.Value.ClassDesc</h4>
    <h3>
        Students:
    </h3>
    <div>
        @foreach (var student in ClassAccesser.Value.Students)
        {
            <span>Name: @student.Name</span>
            <span>Age: @student.Age</span>
        }
    </div>
    
    

    HomeController

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Options;
    
    namespace OptionsBindSample.Controllers
    {
        public class HomeController : Controller
        {
            public IActionResult Index()
            {
                return View();
            }
        }
    }
    

    启动项目得到同样结果

    任务14:配置的热更新

    ASP.NET修改web.config后站点会自动重启实现热更新

    ASP.NET Core不同,实现如下:

    将Index的这一行

    @inject IOptions<OptionsBindSample.Class> ClassAccesser
    

    修改为

    @inject IOptionsSnapshot<OptionsBindSample.Class> ClassAccesser
    

    启动项目

    修改appsettings的ClassNo为222,保存

      "ClassNo": "222",
    

    刷新网页

    实现原理

    对比控制台程序JsonComfigSample的Program读取配置文件

                // 第二个参数表示文件不存在时是否抛异常
                // 第三个参数表示配置文件更新的时候是否重新加载
                var builder = new ConfigurationBuilder()
                    .AddJsonFile("class.json",false,true);
    

    而在ASP.NET Core程序OptionsBindSample在Program中的CreateDefaultBuilder的源码实现了

            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>();
    

    WebHost源码:
    https://github.com/aspnet/MetaPackages/blob/master/src/Microsoft.AspNetCore/WebHost.cs

    源码里面实现热更新(165行)

    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
          .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
    

    由于它是WebHostBuilder的一个扩展函数,所以可以覆盖该方法

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            // 如果业务场景不需要一个线程一直关注配置文件变更,可以关闭热更新
            .ConfigureAppConfiguration(config => { config.AddJsonFile("appsettings.json", false, false); })
            .UseStartup<Startup>();
    

    启动项目,修改配置文件,保存,刷新网页,内容不会热更新

    任务15:配置框架设计浅析

    var builder = new ConfigurationBuilder();// 初始化Builder
    
    builder.Add(source);// 将source添加到Builder
    =>
    JsonConfigurationSource source = new
    JsonConfigurationSource()
    {
        Path = "settings.json";
    };
    
    var configurationRoot = builder.Build();// Build
    =>
    foreach(var source in sources)
    {
        var provider = source.Build();
        providers.add(provider);
    }
    return new ConfigurationRoot(providers);
    
    configurationRoot["Key"]// Use
    =>
    foreach(var provider in providers.Reverse())
    {
        string value;
        provider.TryGet(Key, out Value)
        return value;
    }
    

    知识共享许可协议

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

    欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

    如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

  • 相关阅读:
    4.Eclipse下的Hadoop开发实践
    6.命令行编译打包运行五个MapReduce程序
    1.Hadoop初步环境搭建(ssh无密码通信)
    webkit中对incomplete type指针的处理技巧
    Windows平台编译Webkit
    利用Webkit抓取动态网页和链接
    用C#实现网络爬虫(一)
    C#中delegate对象Equals方法简析
    Webkit客户端进程解析
    用C#实现网络爬虫(二)
  • 原文地址:https://www.cnblogs.com/MingsonZheng/p/11273689.html
Copyright © 2011-2022 走看看