【开源系列】三国演义LBS (五)源码:基础框架:终极反射
前言:
-----------------------------------------------
相关讨论组入口: http://www.pixysoft.net/ (点击进入)
我是如何设计框架的 一:
设计框架,最多用Facade设计模式,整个框架仅仅有一个public class,就是XXXManager。
然后其他一切功能从Manager通过接口暴露出来。
这样从记忆上,用户仅仅需要知道一个Manager,其余的通过IDE的智能提示就能过掌握整个框架的所有功能。
快速入门:
动态方法调用。
比较少用,当初是写IL入门留下来的。主要是针对反射的get/set,使用DynamicMethod取代。
实际使用中,发现虽然单独调用性能很高,但是用在了复杂的逻辑中,没有一丁点的性能优势。
{
// 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去构造一个对象。
{
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。非常常用。
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就是什么样子。
{
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一致,但是性能更好。
{
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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