ASP.NET Core应用基本编程模式[3]:配置多种使用形式

前面演示了针对Startup类型的构造函数注入,表示配置的IConfiguration对象是能够注入Startup类型构造函数中的两个服务对象之一。接下来我们采用Options模式来消费以环境变量形式提供的配置,如下所示的FoobarOptions是我们定义的Options类型。在注册的Startup类型中,可以直接在构造函数中注入IConfiguration服务,并在ConfigureServices方法中将其映射为FoobarOptions类型。在Configure方法中,可以通过注入的IOptions服务得到通过配置绑定的FoobarOptions对象,并将其序列化成JSON字符串。在通过调用IApplicationBuilder的Run方法注册的中间件中,这个JSON字符串直接作为请求的响应内容。

class Program

{

    static void Main()

    {

        Environment.SetEnvironmentVariable("ASPNETCORE_FOOBAR:FOO", "Foo");

        Environment.SetEnvironmentVariable("ASPNETCORE_FOOBAR:BAR", "Bar");

        Environment.SetEnvironmentVariable("ASPNETCORE_Baz", "Baz");

        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder.UseStartup())

            .Build()

            .Run();

    }

    public class Startup

    {

        private readonly IConfiguration _configuration; 

        public Startup(IConfiguration configuration)  => _configuration = configuration;

        public void ConfigureServices(IServiceCollection services) => services.Configure(_configuration);

        public void Configure(IApplicationBuilder app, IOptions optionsAccessor)

        {

            var options = optionsAccessor.Value;

            var json = JsonConvert.SerializeObject(options, Formatting.Indented);

            app.Run(async context =>

            {

                context.Response.ContentType = "text/html";               

                await context.Response.WriteAsync($"

{json}
");

            });

        }

    }

    public class FoobarOptions

    {

        public Foobar Foobar { get; set; }

        public string Baz { get; set; }

    }

    public class Foobar

    {

        public string Foo { get; set; }

        public string Bar { get; set; }

    }

}

为了能够提供绑定为FoobarOptions对象的原始配置,我们在Main方法中设置了3个对应的环境变量,这些环境变量具有相同的前缀“ASPNETCORE_”。应用程序启动之后,如果利用浏览器访问该应用,得到的输出结果如下图所示。

12

二、以键值对形式读取和修改配置

《配置[3]:配置模型总体设计》对配置模型进行了深入分析,由此可知,IConfiguration对象是以字典的结构来存储配置数据的,该接口定义的索引可供我们以键值对的形式来读取和修改配置数据。在ASP.NET Core应用中,我们可以通过调用定义在IWebHostBuilder接口的GetSetting方法和UseSetting方法达到相同的目的。

public interface IWebHostBuilder

{

    string GetSetting(string key);

    IWebHostBuilder UseSetting(string key, string value);

    ...

}

上面演示的实例采用环境变量来提供最终绑定为FoobarOptions对象的原始配置,这样的配置数据也可以通过如下所示的方式调用IWebHostBuilder接口的UseSetting方法来提供。修改后的应用程序启动之后,如果利用浏览器访问该应用,同样可以得到上图所示的输出结果。

class Program

{

    static void Main()

    {

        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder

            .UseSetting("Foobar:Foo", "Foo")

            .UseSetting("Foobar:Bar", "Bar")

            .UseSetting("Baz", "Baz")

            .UseStartup())

        .Build()

        .Run();

    }

}

配置不仅仅供应用程序来使用,ASP.NET Core框架自身的很多特性也都可以通过配置进行定制。如果希望通过修改配置来控制ASP.NET Core框架的某些行为,就需要先知道对应的配置项的名称是什么。例如,ASP.NET Core应用的服务器默认使用launchSettings.json文件定义的监听地址,但是我们可以通过修改配置采用其他的监听地址。包括端口在内的监听地址是通过名称为urls的配置项来控制的,如果记不住这个配置项的名称,也可以直接使用定义在WebHostDefaults中对应的只读属性ServerUrlsKey,该静态类型中还提供了其他一些预定义的配置项名称,所以这也是一个比较重要的类型。

public static class WebHostDefaults

{

    public static readonly string ServerUrlsKey = "urls";

    ...

}

针对上面演示的这个实例,如果希望为服务器设置不同的监听地址,直接调用IWebHostBuilder接口的UseSetting方法将新的地址作为urls配置项的内容即可。既然配置项被命名为urls,就意味着服务器的监听地址不仅限于一个,如果希望设置多个监听地址,我们可以采用分号作为分隔符。

class Program

{

    static void Main()

    {

        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder

            .UseSetting("Foobar:Foo", "Foo")

            .UseSetting("Foobar:Bar", "Bar")

            .UseSetting("Baz", "Baz")

            .UseSetting("urls", "http://0.0.0.0:8888;http://0.0.0.0:9999")

            .UseStartup())

        .Build()

        .Run();

    }

}

为了使实例程序采用不同的监听地址,可以采用如上所示的方式调用IWebHostBuilder接口的UseSetting方法设置两个针对8888和9999端口号的监听地址。由图11-13所示的程序启动后的输出结果可以看出,服务器确实采用我们指定的两个地址监听请求,通过浏览器针对这两个地址发送的请求能够得到相同的结果。

13

除了调用UseSetting方法设置urls配置项来修改服务器的监听地址,直接调用IWebHostBuilder接口的UseUrls扩展方法也可以达到相同的目的。另外,我们提供的监听地址只能包含主机名称/IP地址(Host/IP)和端口号,不能包含基础路径(PathBase)。如果我们提供“http://0.0.0.0/3721/foobar”这样一个URL,系统会抛出一个InvalidOperationException类型的异常。基础路径可以通过注册中间件的方式进行设置。

public static class HostingAbstractionsWebHostBuilderExtensions

{

    public static IWebHostBuilder UseUrls(this IWebHostBuilder hostBuilder, params string[] urls);

}

三、合并配置

在启动一个ASP.NET Core应用时,我们可以自行创建一个承载配置的IConfiguration对象,并通过调用IWebHostBuilder接口的UseConfiguration扩展方法将它与应用自身的配置进行合并。如果应用自身存在重复的配置项,那么该配置项的值会被指定的IConfiguration对象覆盖。

public static class HostingAbstractionsWebHostBuilderExtensions

{

  public static IWebHostBuilder UseConfiguration(this IWebHostBuilder hostBuilder, IConfiguration configuration);

}

如果前面演示的实例需要采用这种方式来提供配置,我们可以对程序代码做如下修改。如下面的代码片段所示,我们创建了一个ConfigurationBuilder对象,并通过调用AddInMemory

Collection扩展方法注册了一个MemoryConfigurationSource对象,它提供了绑定FoobarOptions对象所需的所有配置数据。我们最终利用ConfigurationBuilder创建出一个IConfiguration对象,并通过调用上述UseConfiguration方法将提供的配置数据合并到当前应用中。修改后的应用程序启动之后,如果利用浏览器访问该应用,同样会得到图11-12所示的输出结果。(S1115)

class Program

{

    static void Main()

    {

        var configuration = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary

            {

                ["Foobar:Foo"] = "Foo",

                ["Foobar:Bar"] = "Bar",

                ["Baz"]    = "Baz"

            })

            .Build();

        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder

            .UseConfiguration(configuration)

            .UseStartup())

        .Build()

        .Run();

    }

}

四、注册IConfigurationSource

配置系统最大的特点是可以注册不同的配置源。借助IWebHostBuilder接口的UseConfiguration扩展方法,虽然可以将利用配置系统提供的IConfiguration对象应用到ASP.NET Core程序中,但是这样的整合方式总显得不够彻底,更加理想的方式应该是可以直接在ASP.NET Core应用中注册IConfigurationSource对象。

针对IConfigurationSource的注册可以调用IWebHostBuilder接口的ConfigureAppConfiguration方法来完成,该方法与在IHostBuilder接口上定义的同名方法基本上是等效的。如下面的代码片段所示,这个方法的参数是一个类型为Action的委托对象,这意味着我们可以就承载上下文对配置做针对性设置。如果设置与当前承载上下文无关,我们还可以调用ConfigureAppConfiguration方法重载,该方法的参数类型为Action

public interface IWebHostBuilder

{

    IWebHostBuilder ConfigureAppConfiguration(Action configureDelegate);

}

public static class WebHostBuilderExtensions

{

    public static IWebHostBuilder ConfigureAppConfiguration(this IWebHostBuilder hostBuilder, Action configureDelegate);

}

对于上面演示的这个程序来说,如果将针对IWebHostBuilder接口的UseConfiguration方法的调用替换成如下所示的针对ConfigureAppConfiguration方法的调用,依然可以达到相同的目的。修改后的应用程序启动之后,如果利用浏览器访问该应用,同样会得到上图所示的输出结果。

class Program

{

    static void Main()

    {     

        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder.ConfigureAppConfiguration(config => config

                .AddInMemoryCollection(new Dictionary

                {

                    ["Foobar:Foo"] = "Foo",

                    ["Foobar:Bar"] = "Bar",

                    ["Baz"] = "Baz"

                }))

            .UseStartup())

        .Build()

        .Run();

    }

}

龙华大道1号 http://www.kinghill.cn/Dynamics/2106.html

你可能感兴趣的:(ASP.NET Core应用基本编程模式[3]:配置多种使用形式)