同种类型集合上面可以通过配置实现不同的叫声了,但是一次只能有一个叫声,我们希望根据配置动物名称和叫声的对应关系,当程序指定某种动物的时候,会返回相应的叫声。比如下面的配置:<?xmlversion="1.0"encoding="utf-8"?><configuration><configSections><sectionname="AnimalConfiguration"type="AnimalApplicationBlock.AnimalSettings,AnimalApplicationBlock"/></configSections><AnimalConfigurationdefaultAnimal="Cow"><animalProviders><addname="Dog"type="AnimalApplicationBlock.Animal,AnimalApplicationBlock"word="Arf!"/><addname="Pig"type="AnimalApplicationBlock.Animal,AnimalApplicationBlock"word="Oink!"/><addname="Cow"type="AnimalApplicationBlock.Animal,AnimalApplicationBlock"word="Moooo!"/></animalProviders></AnimalConfiguration></configuration>对应Dog,我们要返回Arf!;对应Pig返回Oink!;对应Cow返回Moooo!。而且,如果没有指定,默认为Cow。先看AnimalSettings的变化:namespaceAnimalApplicationBlock...{publicclassAnimalSettings:SerializableConfigurationSection...{publicconststringSectionName="AnimalConfiguration";privateconststringanimalProviderProperty="animalProviders";privateconststringdefaultAnimalProperty="defaultAnimal";[ConfigurationProperty(animalProviderProperty,IsRequired=true)]publicNameTypeConfigurationElementCollection<AnimalData>AnimalProviders...{get...{return(NameTypeConfigurationElementCollection<AnimalData>)base[animalProviderProperty];}}[ConfigurationProperty(defaultAnimalProperty,IsRequired=true)]publicstringDefaultAnimal...{get...{return(string)base[defaultAnimalProperty];}}}}AnimalProviders属性用来对应多个动物和叫声的对应集合。使用NameTypeConfigurationElementCollection<T>作为类型,AnimalData是继承NameTypeConfigurationElement的。另外,加一个属性用来定义默认动物的名字。AnimalCustomFactory需要做一点改动,最后的返回是,使用settings.AnimalProviders.Get(name)。namespaceAnimalApplicationBlock...{publicclassAnimalCustomFactory:AssemblerBasedCustomFactory<IAnimal,AnimalData>...{protectedoverrideAnimalDataGetConfiguration(stringname,IConfigurationSourceconfigurationSource)...{AnimalSettingssettings=(AnimalSettings)configurationSource.GetSection(AnimalSettings.SectionName);returnsettings.AnimalProviders.Get(name);}}}为了实现默认动物的实现,AnimalFactory加一个CreateAnimal的重载方法。namespaceAnimalApplicationBlock...{publicstaticclassAnimalFactory...{privatestaticAnimalInstanceFactoryfactory=newAnimalInstanceFactory(ConfigurationSourceFactory.Create());publicstaticAnimalCreateAnimal(stringanimalName)...{returnfactory.Create(animalName);}publicstaticAnimalCreateAnimal()...{returnfactory.CreateDefault();}}}这个重载方法是为了使用这个ApplicationBlock的开发人员方便,另外提供一种默认实现的方式,以后可以通过配置默认实现来改变很多程序的相关逻辑。这样就带来了如何找到默认实现的问题,要解决这个问题,需要添加一个类DefaultNameRetriever,用来获取配置的默认动物名。namespaceAnimalApplicationBlock...{publicclassDefaultNameRetriever:IConfigurationNameMapper...{publicstringMapName(stringname,IConfigurationSourceconfigSource)...{returnname!=null?name:((AnimalSettings)configSource.GetSection(AnimalSettings.SectionName)).DefaultAnimal;}}}然后需要在Animal类加上相应的属性ConfigurationNameMapper(typeof(DefaultNameRetriever))。namespaceAnimalApplicationBlock...{[CustomFactory(typeof(AnimalCustomFactory))][ConfigurationNameMapper(typeof(DefaultNameRetriever))]publicclassAnimal...{privatestringwordToSay;publicAnimal():this("Bark!")...{}publicAnimal(stringwordToSay)...{this.wordToSay=wordToSay;}publicstringSpeak()...{returnwordToSay;}}}测试的代码如下[TestMethod]publicvoidPigsSayOink()...{Animalpig=AnimalFactory.CreateAnimal("Pig");Assert.AreEqual("Oink!",pig.Speak());}[TestMethod]publicvoidDogsSayArf()...{Animaldog=AnimalFactory.CreateAnimal("Dog");Assert.AreEqual("Arf!",dog.Speak());}[TestMethod]publicvoidDefaultAnimalIsCow()...{Animalcow=AnimalFactory.CreateAnimal();Assert.AreEqual("Moooo!",cow.Speak());}