.Net配置文件——反射+配置文件存储类型实例

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

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

       

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>";
            //省略。。。。。。。
        }

    }

}

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

  <!--greetingStrategy节点及其处理程序配置-->
  <configSections>
    <section name="greetingStrategy" type="ClassLib.GreetingConfigurationHandler,ClassLib"/>
  </configSections>
  <greetingStrategy type="ClassLib.ChineseGreeting,ClassLib">
    <params greetingType="***中文问候***"/>  <!--构造函数的参数-->
  </greetingStrategy>

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

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

namespace ClassLib
{
    public class GreetingConfigurationHandler : IConfigurationSectionHandler
    {
        /*
         处理有参数的构造函数的对象的创建:
         */
        /// <summary>
        /// 创建配置节处理程序。
        /// </summary>
        /// <param name="parent">父对象。</param>
        /// <param name="configContext">配置上下文对象。</param>
        /// <param name="section">节 XML 节点。</param>
        /// <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文件中的参数,然后在类型实例化的时候传进去;

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

           写个东西测试下:

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

         嘿嘿,相对方便。

      

 

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

时间: 2024-10-27 09:27:14

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

框架-配置文件+反射= spring.net吗

问题描述 配置文件+反射= spring.net吗 最近在学习 spring.net,用到了IOC容器,感觉跟之前用的抽象工厂 配置文件+反射 一样,但是既然我们公司新的框架选择了IOC我相信定有什么不同,查了些资料自己也敲例子但是才疏学浅,理解还是不好,希望知友给个好答案或者好的讨论方向.谢谢大家~~ 解决方案 简单来说就是这样的.用spring.net的人主要是那些习惯了spring的人.本身这就是一个非主流的东西.相比较而言,你可以看下MEF(Managed Extensibility F

Zend Framework教程之配置文件application.ini解析_php实例

本文分析了Zend Framework配置文件application.ini用法.分享给大家供大家参考,具体如下: 最方便,常用的配置方式使用配置文件.配置文件的具体的相关设置选项如下: php.ini的相关的配置选项,具体格式如下: phpSettings.配置选项,例如 phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 includePath相关配置 includePaths.library = APP

思想上移,行动下移——抽象工厂+反射+配置文件

  从网上查找资料的时候发现很多同学都写过这篇博客了,可见我的方向没有跑偏.虽然我们学设计模式的时候已经接触过抽象工厂模式,大话设计模式中每个设计模式都紧密联系生活,而且主人公讲的也相当有趣,但是真正运用起来却没那么简单.可以说小菜只是帮我们理解了各个设计模式的用途以及优缺点,真正的理解还需要我们自己动手实践.   为什么要用抽象工厂?   主要就是为了提高软件的灵活性,运用抽象工厂+反射+配置文件可以很方便的更换数据库.引入接口之后,就可以对外提供一致的接口,而我们既可以用SQLServer实

.Net判断一个对象是否为数值类型实例_实用技巧

本文实例讲述了.Net判断一个对象是否为数值类型的方法,分享给大家供大家参考.具体实现方法如下: .Net判断一个对象是否为数值类型乍一听是个很简单的事,但突然搞起来还真有点无从下手的感觉. 首先当然是通过GetType()方法反射获取其类型信息,然后对其进行分析,但是类型信息Type中并没有简单地给出这么一个属性进行判断. 老外给出的方法是: 复制代码 代码如下: public static bool IsNumeric(this Type dataType) {         if (da

C#中使用反射获取结构体实例

原文:C#中使用反射获取结构体实例 一般用反射获取类对象的实例比较简单,只要类有一个无参构造函数或没有显示声明带参的构造函数即可使用如下代码 static void Main(string[] args) { Type type = typeof(MyObject); object obj = type.GetConstructor(Type.EmptyTypes).Invoke(null); Console.WriteLine(obj); } class MyObject { } 之前我一直没

IMG-后勤执行-仓库管理-主数据-定义存储类型标识符(WM-16)

IMG-后勤执行-仓库管理-主数据-定义存储类型标识符(WM-16)定义存储类型标识符With this indicator you can control whether certain materials are placed into or removed from stock in certain storage types with a higher priority.  This leads to a classification of your materials and allo

虚拟化存储设计:存储类型

Problem Statement 存储设计是虚拟化设计的重要部分之一,确定合适的存储类型是展开存储设计的关键一步. FC/FCoE, iSCSI, NFS 甚至 Local Storage,  你会选择哪一种呢?参见下图. Requirements 客户需要移植物理服务器到VMware虚拟化平台,很多物理服务器使用FC SAN,有的SAN Disk容量大于2T.其中有的服务器运行MS Cluster Service. 有的应用对响应时间的要求很高. Assumptions 目前存储支持部门很熟

iOS网络编程入门:iCloud键值数据存储编程实例

iCloud键值数据存储设计 iCloud键值数据存储编程实例,画面中有两个开关控件,左图是设备1点击"设置iCloud数据"按钮,将控件状态保存到iCloud服务器.右图是设备2画面,过几秒钟后设备2收到变更通知. 配置Xcode工程 使用Xcode创建一个iOS工程,工程创建好之后,选择TAGETS→MyNotes→Summary→Entitlements,我们可以在这里配置授权信息. 然后我们还需要应用设置代码签名标识,代码签名标识需要选择这个配置概要文件的.选择TAGETS→M

类型实例的创建位置、托管对象在托管堆上的结构

1. 值类型实例的创建位置: 对于值类型的实例,CLR在运行时有两种分配方式:(1) 如果该值类型的实例作为类型中的方法 (Method)中的局部变量,则该实例被创建在线程栈上:(2) 如果该值类型的实例作为类型的成员,则该实 例作为引用类型(引用类型在GC堆或者LOH上创建)的实例的一部分,被创建在GC堆上.下面这段代码演示 了这两种情况: public class Test1 ...{ private int i;//上面(2)中的情况,生成Test的实例的同时,int类型的实例i被创建在G