. Net configuration file-reflection + configuration file storage type instance
Configuration File + reflection does remove the tedious selection of statements, bringing a beautiful catch!
First, the following class is improved (connected ):
Namespace ClassLib {////// Interface IGreetingStrategy //////
Editor: v-liuhch CreateTime: 2015/6/28 11:01:58
Public interface IGreetingStrategy {string GreetingType {get;} void SetGreetingWords (ITextControl textContrl );}////// Class EnglishGreeting //////
Editor: v-liuhch CreateTime: 2015/6/28 11:02:38
Public class EnglishGreeting: IGreetingStrategy {public string GreetingType {get {return English;} public void SetGreetingWords (ITextControl textContrl) {textContrl. Text = hello, readers ;}}////// Class ChineseGreeting //////
Editor: v-liuhch CreateTime: 2015/6/28 11:02:56
Public class ChineseGreeting: IGreetingStrategy {private string greetingType; public ChineseGreeting (string greetingType) {this. greetingType = greetingType;} public ChineseGreeting (): this (Chinese) {} public ChineseGreeting (XmlNode section) {XmlAttribute attr = section. selectSingleNode (params ). attributes [greetingType]; // obtain the property value greetingType = attr. value; // Value for the field} public string GreetingType {get { Return greetingType;} public void SetGreetingWords (ITextControl textContrl) {textContrl. Text = Hello, small reader !; }}////// Class GeneralClass: This Class may have many fields, attributes, and methods. Here, it is just a short description. // PS: GeneralClass is a common type, IGreetingStrategy is maintained in this class, which is called Based on polymorphism. //////
Editor: v-liuhch CreateTime: 2015/6/28 11:08:04
Public class GeneralClass {private IGreetingStrategy gs; public GeneralClass (IGreetingStrategy gs) {this. gs = gs;} public string GeneralProperty {get {// do some additional work. Here return + gs is omitted. greetingType + ;}} public void GeneralMethod (ITextControl textContrl) {// do some additional work. gs is omitted here. setGreetingWords (textContrl); textContrl. text = + textContrl. text +; // omitted ....... }}}
Then define the specific class and custom tag handler in the configuration file:
Here, ChineseGreeting is the class we want to use, and the class defined above is to process greetingStrategy;
Next, write the specific implementation of this class:
Namespace ClassLib {public class GreetingConfigurationHandler: IConfigurationSectionHandler {/* process the creation of an object with a parameter constructor :*/////// Create a configuration section handler. //////Parent object. ///Configure the context object. ///Section XML nodes. ///
The node handler object.
///
///
Editor: v-liuhch CreateTime: 2015/6/30 20:34:54
Public object Create (object parent, object configContext, System. xml. xmlNode section) {// obtain the value of the node type attribute Type t = Type. getType (section. attributes [type]. value); object obj = null; try {/* 2, add a constructor to the class of the instance, receive an XmlNode, and pass the greeting_stragetgy node here, then process it in this constructor. * // If t contains a constructor with the xmlnode parameter, directly use this constructor Type [] paras = {typeof (XmlNode)}; ConstructorInfo constructors = t. getConstructor (paras); if (construct Ors! = Null) {object [] paramters = {section}; return Activator. createInstance (t, paramters); // input the parameters of the read constructor} if (section. selectSingleNode (params) = null) // No parameter constructor {obj = Activator. createInstance (t);} else // has a parameter constructor {/* 1. In this class, the policy class is processed, the attribute value of the params node is obtained, and then passed to the specific instantiated class; * /// obtain the value of greetingType of the params node attribute XmlAttribute attr = section. selectSingleNode (params ). attributes [greetingType]; object [] parameters = {attr. value}; obj = Activator. createInstance (t, parameters); // input the read constructor parameter }}catch (Exception) {return null ;} return obj ;}}}
In the creation method, we first determine whether the ChineseGreeting class has a constructor whose parameter is a node. If so, we will directly treat the section as a parameter, when Using Reflection to create a type instance;
Without such a constructor, we will read the parameters in the XML file in this processing class and then pass them in when the type is instantiated;
The two methods are the same, but they are only the result of reading this parameter sooner or later, I think it is more flexible and preferred to read the constructor parameters in the configuration file in this class.
Test writing something:
# Region custom node storage type information -- Reflection Method IGreetingStrategy greetingStrategy = (IGreetingStrategy) ConfigurationManager. GetSection (greetingStrategy); if (greetingStrategy! = Null) {GeneralClass generalClass = new GeneralClass (greetingStrategy); ltrGreetingType. Text = generalClass. GeneralProperty; generalClass. GeneralMethod (ltrGreetingWord);} # endregion
Hey, it's relatively convenient.
I feel that the reflection is strong in extracting the changes, but where is the easiest way to change the changes? Or the maintenance cost is low in the future. So the configuration file should be ready at this time ......