>汽车>>正文

.NET Core的配置[5]: 配置绑定 [下篇]

原标题:.NET Core的配置[5]: 配置绑定 [下篇]

在《.NET Core的配置[4]: 配置绑定 [上篇]》中我们着重介绍了如何将一个配置项的值(字符串)绑定为一个对象,以及将一个配置节绑定为一个符合对象。接下来,我们来介绍针对目标类型为集合和字典的配置绑定

01

绑定集合对象

如果配置绑定的目标类型是一个集合(包括数组),那么当前IConfiguration的每一个子配置节将绑定为集合的元素。假设我们需要将一个IConfiguration对象绑定为一个元素类型为Profile的集合,它表示的配置树应该具有如图1所示的结构。

图1 集合对象的配置树

既然我们能够正确将集合对象通过一个合法的配置树体现出来,那么我们就可以将它转换成配置字典。对于通过图1表示的这个包含三个元素的Profile集合,我们可以采用如表1所示的结构来定义对应的配置字典。

表1 针对集合的配置数据结构

我们依然通过一个简单的实例来演示针对集合的配置绑定。如下面的代码片段所示,我们创建了一个ConfigurationBuilder对象并为之添加了一个MemoryConfigurationProvider,后者按照如表1所示的结构提供了原始的配置数据。我们利用这个MemoryConfigurationSource对象创建的IConfiguration对象并调用这个它的Get方法将Key为“Profiles”的配置节绑定为一个List<Profile>对象。

在下面演示的代码片段中,我们按照表1所示的结构定义了一个Dictionary<string, string>对象,然后以此用创建了一个MemoryConfigurationSource,并将其注册到创建的ConfigurationBuilder对象。我们利用后者生成的配置分别绑定为一个集合(目标类型设置为IEnumerable<Profile>)和一个数组。

我们在上面提到过,IConfigurationProvider通过GetChildKeys提供的键值是经过排序的,所以在绑定生成的集合或者数组中的元素的顺序是与配置源中不相同的,如下的调试断言也体现了这一点。

varsource = newDictionary< string, string>

{

[ "foo:gender"] = "Male",

[ "foo:age"] = "18",

[ "foo:contactInfo:emailAddress"] = "foo@outlook.com",

[ "foo:contactInfo:phoneNo"] = "123",

[ "bar:gender"] = "Male",

[ "bar:age"] = "25",

[ "bar:contactInfo:emailAddress"] = "bar@outlook.com",

[ "bar:contactInfo:phoneNo"] = "456",

[ "baz:gender"] = "Female",

[ "baz:age"] = "36",

[ "baz:contactInfo:emailAddress"] = "baz@outlook.com",

[ "baz:contactInfo:phoneNo"] = "789"

};

varconfiguration = newConfigurationBuilder()

.AddInMemoryCollection(source)

.Build();

varprofiles = newProfile[]

{

newProfile(Gender.Male, 18, "foo@outlook.com", "123"),

newProfile(Gender.Male, 25, "bar@outlook.com", "456"),

newProfile(Gender.Female, 36, "baz@outlook.com", "789"),

};

varconfiguration = newConfigurationBuilder()

.AddInMemoryCollection(source)

.Build();

varcollection = configuration.Get<IEnumerable<Profile>>();

Debug.Assert(collection.Any(it => it.Equals(profiles[ 0])));

Debug.Assert(collection.Any(it => it.Equals(profiles[ 1])));

Debug.Assert(collection.Any(it => it.Equals(profiles[ 2])));

vararray = configuration.Get<Profile[]>();

Debug.Assert(array[ 0].Equals(profiles[ 1]));

Debug.Assert(array[ 1].Equals(profiles[ 2]));

Debug.Assert(array[ 2].Equals(profiles[ 0]));

在进行针对集合类型配置绑定过程中,如果某个配置节绑定失败,该配置节将被忽略并选择下一个配置节继续进行绑定。但是如果目标类型为数组,最终绑定生成的数组长度与子配置节的个数总是一致的,绑定失败的元素将被甚至为Null。

比如我们将上面的程序作了如下的改写,保存原始配置的字典对象包含两个元素,第一个元素的性别从“Male”改为“男”,毫无疑问这个值是不可能转换成Gender枚举对象的,所以针对这个Profile的配置绑定会失败。如果将目标类型设置为IEnumerable<Profile>,那么最终生成的集合只会有2个元素,倘若目标类型切换成Profile数组,数组的长度依然为3,但是第一个元素是Null。

varsource = newDictionary< string, string>

{

[ "foo:gender"] = "男",

[ "foo:age"] = "18",

[ "foo:contactInfo:emailAddress"] = "foo@outlook.com",

[ "foo:contactInfo:phoneNo"] = "123",

[ "bar:gender"] = "Male",

[ "bar:age"] = "25",

[ "bar:contactInfo:emailAddress"] = "bar@outlook.com",

[ "bar:contactInfo:phoneNo"] = "456",

[ "baz:gender"] = "Female",

[ "baz:age"] = "36",

[ "baz:contactInfo:emailAddress"] = "baz@outlook.com",

[ "baz:contactInfo:phoneNo"] = "789"

};

varconfiguration = newConfigurationBuilder()

.AddInMemoryCollection(source)

.Build();

varcollection = configuration.Get<IEnumerable<Profile>>();

Debug.Assert(collection.Count() == 2);

vararray = configuration.Get<Profile[]>();

Debug.Assert(array.Length == 3);

Debug.Assert(array[ 2] == null);

02

绑定字典

能够通过配置绑定生成的字典是一个实现了IDictionary<string,T>的类型,也就是说配置模型没有对字典的Value未作任何要求,但是字典对象的Key必须是一个字符串或者枚举。

如果采用配置树的形式来表示这么一个字典对象,我们会发现它与针对集合的配置树在结构上是完全一样的。唯一的区别是,集合元素的索引直接变成了字典元素的Key。也就是说图1所示的这棵配置树同样可以表示成一个具有三个元素的Dictionary<string, Profile>对象 ,它们对应的Key分别是“Foo”、“Bar”和“Baz”。

varsource = newDictionary< string, string>

{

[ "foo:gender"] = "男",

[ "foo:age"] = "18",

[ "foo:contactInfo:emailAddress"] = "foo@outlook.com",

[ "foo:contactInfo:phoneNo"] = "123",

[ "bar:gender"] = "Male",

[ "bar:age"] = "25",

[ "bar:contactInfo:emailAddress"] = "bar@outlook.com",

[ "bar:contactInfo:phoneNo"] = "456",

[ "baz:gender"] = "Female",

[ "baz:age"] = "36",

[ "baz:contactInfo:emailAddress"] = "baz@outlook.com",

[ "baz:contactInfo:phoneNo"] = "789"

};

varconfiguration = newConfigurationBuilder()

.AddInMemoryCollection(source)

.Build();

varprofiles = configuration

.Get<IDictionary< string, Profile>>();

Debug.Assert(profiles[ "foo"].Equals(

newProfile(Gender.Male, 18, "foo@outlook.com", "123")));

Debug.Assert(profiles[ "bar"].Equals(

newProfile(Gender.Male, 25, "bar@outlook.com", "456")));

Debug.Assert(profiles[ "baz"].Equals(

newProfile(Gender.Female, 36, "baz@outlook.com", "789")));

前情回顾

.NET Core的配置[1]: 读取配置信息[上篇]

.NET Core的配置[2]: 读取配置信息[下篇]

.NET Core的配置[3]: 配置模型详解

.NET Core的配置[4]: 配置绑定 [上篇]返回搜狐,查看更多

责任编辑:

声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()
投诉
免费获取
今日搜狐热点
今日推荐