• 【开源系列】三国演义LBS (五)源码:基础框架:终极反射


    前言

    -----------------------------------------------

    相关讨论组入口: http://www.pixysoft.net/ (点击进入)

      

    我是如何设计框架的 一

    -----------------------------------------------  

    设计框架,最多用Facade设计模式,整个框架仅仅有一个public class,就是XXXManager。

    然后其他一切功能从Manager通过接口暴露出来。

    这样从记忆上,用户仅仅需要知道一个Manager,其余的通过IDE的智能提示就能过掌握整个框架的所有功能。 

    快速入门

    -----------------------------------------------  

    动态方法调用。

    比较少用,当初是写IL入门留下来的。主要是针对反射的get/set,使用DynamicMethod取代。

    实际使用中,发现虽然单独调用性能很高,但是用在了复杂的逻辑中,没有一丁点的性能优势。

            public void test001()
            {
                
    // 100000
                
    //reflection
                
    //    Time Elapsed:        631ms
                
    //    CPU time:        515,625,000ns
                
    //    Gen 0:             0
                
    //    Gen 1:             0
                
    //    Gen 2:             0

                
    //dynamic
                
    //    Time Elapsed:        253ms
                
    //    CPU time:        250,000,000ns
                
    //    Gen 0:             132
                
    //    Gen 1:             0
                
    //    Gen 2:             0


                SomeClass c 
    = new SomeClass();

                CodeTimer.Initialize();

                CodeTimer.Time(
    "reflection"100000delegate()
                {
                    FieldInfo field 
    = c.GetType().GetField("sname");
                    field.SetValue(c, 
    "test");
                    field.GetValue(c);
                });


                CodeTimer.Time(
    "dynamic"100000delegate()
                {
                    IDynamicType dtype 
    = ReflectionManager.CreateDynamicType(c.GetType());
                    IDynamicFieldInfo dfield 
    = dtype.GetField("sname");
                    dfield.SetValue(c, 
    "test");
                    dfield.GetValue(c);
                });
            } 

    创建接口的实现

    这个非常常用。不需要自己需实现借口。具体好处就不多说了,底层就是使用了IL去构造一个对象。

        public interface IPojoValue
        {
            
    string Name { get;set;}

            
    byte[] Image { get;set;}

            List
    <string> Names { get;set;}
        }


                IPojoValue o 
    = ReflectionManager.CreatePojo<IPojoValue>();
                o.Name 
    = "hello";
                o.Names.Add(
    "hello");
                Console.WriteLine(o.Name);
                Console.WriteLine(o.Names[
    0]);

    // 这个非常常用。
     

    BeanMap

    在Java里面经常使用,就是对2个对象进行数值映射。同时,通过通用的GetValue()/SetValue()获取、设置值。如果用反射,性能惨不忍睹,因此有了这个BeanMap。非常常用

                IBeanMap map = ReflectionManager.CreateBeanMap(new SimpleObject());

                
    foreach (string key in map.Keys)
                {
                    Console.Write(key 
    + "::");
                    Console.WriteLine(map.GetValue(key));
                }

                map.SetValue(
    "Age"1313);

                Console.WriteLine(map.GetBean
    <SimpleObject>().Age);



        
    class SimpleObject
        {
            
    string name = "helloworld";
            
    int age = 12;
            
    int? nage = null;
            SimpleObject2 obj 
    = new SimpleObject2();

            
    public int Age
            {
                
    get { return age; }
                
    set { age = value; }
            }

            
    public int? Nage
            {
                
    get
                {
                    
    return this.nage;
                }
                
    set
                {
                    
    this.nage = value;
                }
            }
            
    public string Name
            {
                
    get { return name; }
                
    set { name = value; }
            }

            
    public SimpleObject2 Obj
            {
                
    get { return obj; }
                
    set { obj = value; }
            }
        } 

    使用IL创建反射的替代类DummyType

    微软提供的反射Type性能比较差,因此我使用了IL自己定义了DummyType,结构上与Type一致,但是由于使用了IL创建,因此第一次获取之后,再获取DummyType性能非常高。

    基本上微软的Type是什么样子,我的DummyType就是什么样子。 

                Pixysoft.Tools.CodeTimer.Time("emit with handler cache"100000delegate()
                {
                    
    foreach (IDummyPropertyInfo info in ReflectionManager.CreateDummyType(p.GetType()).GetProperties())
                    {
                        
    string name = info.Name;
                        IDummyType type 
    = info.PropertyType;
                    }

                    
    foreach (IDummyMethodInfo info in ReflectionManager.CreateDummyType(p.GetType()).GetMethods())
                    {
                        
    string name = info.Name;
                        IDummyType type 
    = info.ReturnType;
                    }
                }); 

    创建透明代理

    常用。微软提供了RealProxy, MessageSink 2种机制实现AOP,MessageSink这种性能非常低下不考虑,RealProxy虽然性能高,局限性太大。

    因此我使用了IL,自己设计了一套DynamicProxy,操作与RealProxy一致,但是性能更好。

        class AADynamicProxy : DynamicProxy
        {
            
    public AADynamicProxy()
                : 
    base(typeof(IAA))
            {
            }

            
    public override IDynamicMethodReturnMessage Invoke(IDynamicMethodCallMessage msg)
            {
                
    return base.SyncProcessMessage(msg);
            }
        }

        
    public interface IAA : ICloneable
        {
            
    int Name { get;set;}
        }


            
    public void test000()
            {
                AADynamicProxy proxy 
    = new AADynamicProxy();
                IAA obj 
    = (IAA)proxy.GetTransparentProxy();
                Console.WriteLine(obj.Name);
            } 

    上面的例子,就是使用动态代理模拟了IAA接口。可以看出,与RealProxy的实现是一模一样的,因为我完全模拟的微软的API。 

    以上所有的例子可以在项目的.testdriven目录下找到,还包括了性能测试代码。 

    所有框架已经在大型系统中使用,bug接近0. 放心使用,哈哈哈! 

    下期预告:

    -----------------------------------------------    

    Pixysoft.Framework.Logs,日志框架,使用XML进行记录,并实现了日志分析与提取。

    现在我所有系统都使用了这个日志框架,只要发现有warning级别以上的日志,立刻通过Email回发到我的中央系统,进行数据分析。

    非常方便。 


    附件下载

    -----------------------------------------------    

    Pixysoft.Framework.Reflections 打包下载: 

    http://www.boxcn.net/shared/s2rthsz7k6 

    SVN:

    http://qun.qq.com/air/#95755843/bbs 

  • 相关阅读:
    selenium 常见操作,使用 select 类来处理 下拉列表操作
    selenium 常见操作,使用 ActionChains 类来进行鼠标操作
    selenium 常见元素操作:三大切换--浏览器窗口切换、iframe 窗口切换、alert弹窗切换
    Python selenium 启动浏览器有无界面执行
    selenium 常见元素操作:三大等待---强制等待、隐性等待、显性等待
    web自动化测试中的八大定位方法,推荐使用xpath
    Python 中 WebElement 类中的部分操作
    selenium 启动浏览器后基本操作:后退、前进、刷新、关闭窗口、关闭会话
    selenium webdriver 启动火狐、谷歌、IE浏览器及插件下载地址
    web 页面组成之 HTML页面的 标签类型 及 input 控件
  • 原文地址:https://www.cnblogs.com/zc22/p/2031072.html
Copyright © 2020-2023  润新知