配置文件+反射确实去除了选择语句的繁琐,带来了优美的赶脚!

首先改进了一下类(接上文):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
namespace ClassLib
{
    /// <summary>
    /// Interface IGreetingStrategy
    /// </summary>
    /// <remarks>Editor:v-liuhch CreateTime:2015/6/28 11:01:58</remarks>
    public interface IGreetingStrategy
    {
        string GreetingType { get; }
        void SetGreetingWords(ITextControl textContrl);
    }
 
    /// <summary>
    /// Class EnglishGreeting
    /// </summary>
    /// <remarks>Editor:v-liuhch CreateTime:2015/6/28 11:02:38</remarks>
    public class EnglishGreeting : IGreetingStrategy
    {
        public string GreetingType
        {
            get { return English; }
        }
 
        public void SetGreetingWords(ITextControl textContrl)
        {
            textContrl.Text = hello,readers;
        }
    }
 
    /// <summary>
    /// Class ChineseGreeting
    /// </summary>
    /// <remarks>Editor:v-liuhch CreateTime:2015/6/28 11:02:56</remarks>
    public class ChineseGreeting : IGreetingStrategy
    {
        private string greetingType;
        public ChineseGreeting(string greetingType)
        {
 
            this.greetingType = greetingType;
        }
        public ChineseGreeting() : this(中文) { }
        public ChineseGreeting(XmlNode section) {
            XmlAttribute attr = section.SelectSingleNode(params).Attributes[greetingType];//获取属性值
            greetingType = attr.Value;//为字段赋值
        }
        public string GreetingType
        {
            get { return greetingType; }
        }
 
        public void SetGreetingWords(ITextControl textContrl)
        {
            textContrl.Text = 你好啊,小读者!;
        }
    }
 
    /// <summary>
    /// Class GeneralClass:这个类可能还有很多的字段,属性,方法,这里只是简写下
    /// PS:GeneralClass是一个普通的类型,这个类内部维护着IGreetingStrategy,调用的时候还是根据多态具体调用。
    /// </summary>
    /// <remarks>Editor:v-liuhch CreateTime:2015/6/28 11:08:04</remarks>
    public class GeneralClass
    {
        private IGreetingStrategy gs;
        public GeneralClass(IGreetingStrategy gs)
        {
            this.gs = gs;
        }
        public string GeneralProperty
        {
            get
            {
                //做一些额外的工作,这里省略
                return <span sytle="color:red"> + gs.GreetingType + </span>;
            }
        }
        public void GeneralMethod(ITextControl textContrl)
        {
            //做一些额外的工作,这里省略
            gs.SetGreetingWords(textContrl);
            textContrl.Text = <span sytle="color:red"> + textContrl.Text + </span>;
            //省略。。。。。。。
        }
 
 
    }
 
}

然后在配置文件中定义好我们要使用的具体类和自定义标签的处理程序:

1
2
3
4
5
6
<!--greetingStrategy节点及其处理程序配置-->
<configsections><section name="greetingStrategy" type="ClassLib.GreetingConfigurationHandler,ClassLib/">
 
<greetingstrategy type="ClassLib.ChineseGreeting,ClassLib">
  <params greetingtype="***中文问候***">  <!--构造函数的参数-->
</params></greetingstrategy></section></configsections>

这里,ChineseGreeting是我们要使用的类,上面定义的是处理greetingStrategy的类;

接着,写这个类的具体实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
namespace ClassLib
{
    public class GreetingConfigurationHandler : IConfigurationSectionHandler
    {
        /*
         处理有参数的构造函数的对象的创建:
         */
        /// <summary>
        /// 创建配置节处理程序。
        /// </summary>
        ///<param name="parent">父对象。
        ///<param name="configContext">配置上下文对象。
        ///<param name="section">节 XML 节点。
        /// <returns>创建的节处理程序对象。</returns>
        /// <exception cref="System.NotImplementedException"></exception>
        /// <remarks>Editor:v-liuhch CreateTime:2015/6/30 20:34:54</remarks>
        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            //获取节点type属性的值
            Type t = Type.GetType(section.Attributes[type].Value);
            object obj=null;
 
            try
            {
                /* 2,在要实例的类中加入一个构造函数,接收一个XmlNode节点,将greeting_stragetgy的节点在此传递,然后在这个构造函数中进行处理;*/
                //如果t包含有参数为xmlnode的构造函数,直接使用这个构造函数
                Type[] paras = { typeof(XmlNode) };
                ConstructorInfo constructors = t.GetConstructor(paras);
                if (constructors != null)
                {
                    object[] paramters = { section };
                    return Activator.CreateInstance(t, paramters); //传入读取到的构造函数的参数
                }
 
                if (section.SelectSingleNode(params) == null//无参数构造函数
                {
                    obj = Activator.CreateInstance(t);
                }
                else  //有参数构造函数
                {
                    /*1,在此类中对策略类进行处理,取得params节点的属性值,然后传递给具体实例化的类;*/
 
                    //获取params节点的属性greetingType的值
                    XmlAttribute attr = section.SelectSingleNode(params).Attributes[greetingType];
                    object[] parameters = { attr.Value };
                    obj = Activator.CreateInstance(t, parameters); //传入读取到的构造函数的参数
                }
            }
            catch (Exception)
            {
 
                return null;
            }
             
            return obj ;
        }
    }
}

在创建方法中,我们先判断ChineseGreeting类有没有一个参数为节点的构造方法,如果有的话,就直接将section当作参数,在利用反射创建类型实例的时候传进去;

如果没有这样的构造方法,我们就在这个处理类里面读取XML文件中的参数,然后在类型实例化的时候传进去;

两种方式比较,其实都是一样的,只过是这个参数读取的早晚的问题;个人对比了下,觉得在这个类里面读取配置文件中的构造函数参数的方式更加灵活,个人偏爱。

写个东西测试下:

1
2
3
4
5
6
7
8
9
#region 自定义节点存储类型信息——反射方法
           IGreetingStrategy greetingStrategy = (IGreetingStrategy)ConfigurationManager.GetSection(greetingStrategy);
           if (greetingStrategy != null)
           {
               GeneralClass generalClass = new GeneralClass(greetingStrategy);
               ltrGreetingType.Text = generalClass.GeneralProperty;
               generalClass.GeneralMethod(ltrGreetingWord);
           }
           #endregion

嘿嘿,相对方便。

 
 

感觉反射强大在把变化抽出来,但是抽出来的这个变化放到哪里去最容易改动或者是后期维护成本较低,于是配置文件这时候就该上了。。。。。。

http://www.2cto.com/kf/201507/412924.html

.Net配置文件——反射+配置文件存储类型实例的更多相关文章

  1. .Net 中的反射(动态创建类型实例) - Part.4

    动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...

  2. .Net 中的反射(动态创建类型实例)

    动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...

  3. 第三节:工厂+反射+配置文件(手写IOC)对缓存进行管理。

    一. 章前小节 在前面的两个章节,我们运用依赖倒置原则,分别对 System.Web.Caching.Cache和 System.Runtime.Cacheing两类缓存进行了封装,并形成了ICach ...

  4. 【C#反射】动态创建类型实例

    转载自:https://www.cnblogs.com/dytes/archive/2012/06/29/2569488.html .NET中除了构造函数外,还有多种方式可以创建类型的实例.下面总结了 ...

  5. .Net 中的反射(查看基本类型信息) - Part.2

    反射概述 和Type类 1.反射的作用 简单来说,反射提供这样几个能力:1.查看和遍历类型(及其成员)的基本信息和程序集元数据(metadata):2.迟绑定(Late-Binding)方法和属性.3 ...

  6. .Net 中的反射(查看基本类型信息)

    反射概述 和Type类 1.反射的作用 简单来说,反射提供这样几个能力:1.查看和遍历类型(及其成员)的基本信息和程序集元数据(metadata):2.迟绑定(Late-Binding)方法和属性.3 ...

  7. c 存储类型

    1,c语言中的存储类型(定义变量和函数的可见范围和生命周期)这些说明符放置在它们所修饰的类型之前.下面列出 C 程序中可用的存储类: auto register static extern 2,aut ...

  8. python操作Redis安装、支持存储类型、普通连接、连接池

    一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...

  9. Springboot 之 自定义配置文件及读取配置文件注意:配置文件中的字符串不要有下划线 .配置中 key不能带下划线,value可以(下划线的坑,坑了我两天..特此纪念)

    注意:配置文件中的字符串不要有下划线 .配置中  key不能带下划线,value可以 错误的.不能读取的例子: mySet .ABAP_AS_POOLED      =  ABAP_AS_WITH_P ...

随机推荐

  1. Android开发(三十一)——重复引用包错误Conversion to Dalvik format failed

    错误:Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Landroid/sup ...

  2. 如何配置ssh免密码登录

    [TOC] 如果你在管理一堆unix机器,每次登录都要输入密码是挺烦的事情,一方面为了安全我们一般不会将所有机器的密码都设置成一样,另一方面就算一样每次都输入一遍也很麻烦. 这种情况下我们一般是用ss ...

  3. java -jar shell 启动、停止

    启用 vi start.sh #!/bin/sh # ################################################################## # Powe ...

  4. iOS开发——高级技术精选&底层开发之越狱开发第一篇

    底层开发之越狱开发第一篇 做越狱开发也有一些时间了,有很多东西想总结一下,希望给他人一些借鉴,也是自己对过去开发经历的一些总结.个人不推荐使用盗版,这里主要以技术介绍为主. 这个系列里面主要介绍怎样进 ...

  5. Cocos2d-JS项目之四:UI界面的优化

    测试环境: iphone4.iOS6.1.2.chrome 37.2062.60,Cocos2d-js 3.6 之前写了不少,实际项目也按这个去优化了,也有效果,但到最后才发现,尼玛,之前都搞错了,之 ...

  6. ivqBlog 开源博客 (angularjs + express + mongodb)

    转向做全职前端差不多一年的时间了,其中学习了构建工具grunt,gulp,angularjs,coffeescript,less,sass,自己想要做全栈开发,所以自学了mongodb,nodejs, ...

  7. CORS Cookie,和nodejs中的具体实现

    CORS(跨来源资源共享协议),高级浏览器(Chrome,firefox, opera, safir, ie10)在 XMLHttpRequest(AJAX) 中已经支持了这个协议.可以实现ajax跨 ...

  8. 将j-ui(dwz)套用到thinkphp注意事项

    目前我用的 thinkphp 版本是  3.1.3 J-UI  dwz 版本好像是 1.4 现在 j-ui有 thinkphp的例子了,请尽量以他们原创为主,我这里都是一些自己搜集和自己钻研的土办法, ...

  9. php socket

    socket demo代码如下 : server: server.php <?php //phpinfo(); //确保在连接客户端时不会超时 set_time_limit(0); $ip = ...

  10. WIN7 64位如何添加网络打印机

    http://wenku.baidu.com/view/2d64bef0f61fb7360b4c65ac.html 该文介绍的比较详细,并且我按照他的方法,确实安装成功了.