【开源系列】三国演义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 " 100000 delegate ()
            {
                FieldInfo field 
=  c.GetType().GetField( " sname " );
                field.SetValue(c, 
" test " );
                field.GetValue(c);
            });


            CodeTimer.Time(
" dynamic " 100000 delegate ()
            {
                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 " 100000 delegate ()
            {
                
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 

 

 

 

转载于:https://www.cnblogs.com/zc22/archive/2011/04/28/2031072.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值