【开源系列】三国演义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 

原文地址:https://www.cnblogs.com/zc22/p/2031072.html