前言:
-----------------------------------------------
相关讨论组入口: 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: