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

 

 

 

posted @     阅读(2300)  评论(7编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2010-04-28 Pixysoft.Framework.Reports 开发实录
2007-04-28 Attention! .net 持久层正式发布 :Noebe
IT民工
点击右上角即可分享
微信分享提示