Female

接下来我们编写了如下的代码来演示如何采用Options模式来获取由配置文件提供的数据绑定生成的Options对象。我们调用扩展方法AddJsonFile将针对配置文件(“profile.json”)的配置源注册到创建的ConfigurationBuilder对象上,然后利用后者创建出对应的IConfigurataion对象。

}

publicContactInfo ContactInfo { get; set; }

接下来我们创建一个ServiceCollection对象,在调用扩展方法AddOptions注册Options编程模式的核心服务后,我们将创建的IConfiguration对象作为参数调用另一个扩展方法Configure<Profile>。Configure<Profile>方法相当于将提供的IConfiguration与Options类型(Profile)做了一个映射,在需要提供对应Options对象的时候,
映射的IConfiguration对象会被提取出来并绑定为提供的Options对象。

.BuildServiceProvider();

print(optionsAccessor.Get( “bar”));

美高梅注册 1

同样是针对我们上面演示的这个实例,假设现在我们的应用需要采用Options模式提取针对不同用户的信息,具有又该如何实现呢?由于我们采用JSON格式的配置文件来提供原始的用户信息,所以我们需要将针对多个用户的信息定义在profile.json文件中。我们通过如下的形式提供了两个用户(“foo”和“bar”)的基本信息。

PhoneNo = phoneNo

“gender”: “Female”,

美高梅注册,publicProfile(Gender gender, intage, stringemailAddress, stringphoneNo)

“phoneNo”: “123”

原标题:[.NET Core的Options模式] 针对Options对象的依赖注入[上篇]

.SetBasePath(Directory.GetCurrentDirectory())

};

PhoneNo == other.PhoneNo;

Male,

“contactInfo”: {

Console.WriteLine( $”Age: {profile.Age}”);

? false

{

综上所述,我们需要为当前项目添加针对如下三个NuGet包的依赖:

.SetBasePath(Directory.GetCurrentDirectory())

01

EmailAddress = emailAddress,

varconfiguration = newConfigurationBuilder()

}

.BuildServiceProvider()

“age”: “25”,

}

Age == other.Age &&

publicProfile(){ }

Options模式的核心接口IOptions<TOptions>和其他核心类型定义在“Microsoft.Extensions.Options”这个NuGet包中,而NuGet“Microsoft.Extensions.Options.ConfigurationExtensions”实现了针对配置模型的集成,但是由于后者依赖前者,所以我们只需要添加针对后者的依赖就可以了。

}

}

针对同一个Options类型,通过IOptions<TOptions>接口表示的服务只能提供一个单一的Options对象,但是在很多情况下我们需要多个具有相同类型的Options对象来承载不同的配置。

“phoneNo”: “123456789”

Console.WriteLine( $”Email Address:
{profile.ContactInfo.EmailAddress}”);

publicboolEquals(Profile other)

.Value;

Console.WriteLine( $”Age: {profile.Age}”);

接下来我们需要为项目添加相关的NuGet包。由于我们采用基于JSON文件的配置,所以需要添加对应的NuGet包“Microsoft.Extensions.Configuration.Json”。由于Options模式本质上就是借助于依赖注入框架实现的一种编程模式,所以我们需要
“Microsoft.Extensions.DependencyInjection”这个NuGet包。

具名Options的注册和提取体现在如下所示的代码片段中。我们从这段代码片段中可以看出,在调用IServiceCollection接口的扩展方法Configure<Profile>的时候,我们给注册的映射关系起了一个名字(“foo”和“bar”),指定的IConfiguration对象也由原来的ConfigurationRoot对象变成它的两个子配置节。

Action<Profile> print = profile =>

{

{

}

{

};

{

{

classProgram

}

02

Console.WriteLine( $”Email Address:
{profile.ContactInfo.EmailAddress}”);

}

returnother == null

{

“contactInfo”: {

ContactInfo = newContactInfo

}

returnother == null

? false

: Gender == other.Gender &&

所谓的Options模式,其本质就是利用预先注册的一些服务来提供承载配置数据的Options对象,这些原始的数据可能来源于配置系统提供的IConfiguration对象,也可能是我们在应用启动过程中自动创建并初始化的。我们先来演示采用配置系统作为Options对象数据源的场景。简单起见,我们依然沿用《配置》系列定义的Profile作为基础的Options类型,如下是相关类型的定义。

}

Console.WriteLine( $”Phone No: {profile.ContactInfo.PhoneNo}”);

.AddJsonFile( “profile.json”)

.Configure<Profile>(configuration)

}

publicclassProfile:IEquatable<Profile>

我们可以利用配置绑定功能将承载一组相关配置数据的IConfiguration对象转换成一个具有兼容数据结构的POCO(Plain
Old CLR
Object)对象,进而实现“面向对象”的配置编程,而系列介绍的“Options模式(Pattern)”则在此基础上更进了一步,它使我们可以采用依赖注入的方式直接使用绑定的这个POCO对象,我们称这个POCO对象为Options对象。除此之外,Options模式也可以直接脱离配置系统,使我们可以直接采用编程的方式来初始化Options对象。

提供具名的Options

varserviceProvider = newServiceCollection()

{

varconfiguration = newConfigurationBuilder()

.Build();

图1 绑定配置生成的Profile对象

{

.AddOptions()

classProgram

{

}

  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.Options.ConfigurationExtensions

Console.WriteLine( $”Gender: {profile.Gender}”);

publicboolEquals(ContactInfo other)

我们将这个Profile对象承载的相关数据直接打印在控制台上。这个程序执行之后,会在控制台上生成如图1所示的输出结果,可见我们通过Options模式得到Profile对象承载的数据完全来源于配置文件。

Console.WriteLine( $”Gender: {profile.Gender}”);

{

{

承载配置数据的Options对象最终是通过IOptions<TOptions>接口表示的服务来提供的,这个接口的泛型参数TOptions表示的正是Options对象的类型。在得到作为DI容器的IServiceProvider对象之后,我们直接调用其扩展方法GetRequiredService的来提供这个IOptions<Profile>对象,该对象Value属性返回的就是通过绑定配置数据生成的Profile对象。

staticvoidMain()

}

}

},

print(optionsAccessor.Get( “foo”));

.Build();

.Configure<Profile>( “bar”, configuration.GetSection( “bar”))

.AddOptions()

publicclassContactInfo:IEquatable<ContactInfo>

publicstringPhoneNo { get; set; }

{

publicstringEmailAddress { get; set; }

Gender = gender;

图2
根据用户名称提取对应的Profile
返回搜狐,查看更多

: EmailAddress == other.EmailAddress &&

ContactInfo.Equals(other.ContactInfo);

Age = age;

publicGender Gender { get; set; }

Console.WriteLine( $”Phone No: {profile.ContactInfo.PhoneNo}n”);

“phoneNo”: “456”

“foo”: {

.AddJsonFile( “profile.json”)

varprofile = newServiceCollection()

varoptionsAccessor =
serviceProvider.GetRequiredService<IOptionsSnapshot<Profile>>();

}

.Configure<Profile>( “foo”, configuration.GetSection( “foo”))

{

“gender”: “Male”,

就我们演示实例中用来表示个人信息的Profile类型来说,应用程序中可能会使用它来表示不同用户的信息,比如张三、李四和王五。为了解决这个问题,我们可以在添加IConfiguration对象与Options类型映射关系的时候赋予它们一个唯一标识,这个标识最终被用于针对性的提取对应的Options对象。这种具名的Options对象由另一个名为IOptionsSnapshot<TOptions>的接口表示的服务来提供。

“age”: “18”,

“emailAddress”: “bar@outlook.com”,

在一个简单的控制台应用中定义了上面这些类型之后,我们来创建承载一个Profile对象的配置文件profile.json。如下所示的就是这个JSON文件的内容,它提供了一个构成一个完整Profile对象的所有数据。

“age”: “18”,

“contactInfo”: {

publicintAge { get; set; }

staticvoidMain()

“emailAddress”: “foo@outlook.com”,

publicenumGender

责任编辑:

为了针对指定的用户名来提取对应的Profile对象,我们利用作为DI容器的ServiceProvider得到通过IOptionsSnapshot<TOptions>接口表示的服务对象,并将用户名作为参数调用其Get方法得到对应的Profile对象。程序运行后,针对两个不同用户的基本信息将以如图2所示的形式输出到控制台上。

.GetRequiredService<IOptions<Profile>>()

}

以DI的方式使用Options

“bar”: {

“emailAddress”: “foobar@outlook.com”,

“gender”: “Male”,

相关文章