本文不是介绍如何使用Castle.DynamicProxy库,而是介绍利用它进行二次开发,下面通过一个例子,讲解如何实现。
例子的场景:实例化一个类,该类实现了某一个接口,通过接口实现业务功能的调用。下面分别以传统和DynamicProxy两种方式介绍。
(一)传统的方式
接口和类的定义:
public interface IHello
{
string GetString(string msg);
}
public class Hello:IHello
{
public string GetString(string msg)
{
string str = "Hello ";
return str + msg;
}
}
场景实现:
IHello hello = new Hello() as IHello;
MessageBox.Show(hello.GetString());
(二)DynamicProxy方式
利用DynamicProxy二次开发,实现上面的场景,首先只定义接口IHello,而不定义实现类Hello,Hello类的定义利用DynamicPorxy
动态实现,
[CLSCompliant(false)]
public class MyGenerator
{
public static IHello GenerateHello()
{
ModuleScope scope = new ModuleScope();
EasyType typeBuilder = new EasyType(scope, "MyHello", typeof(object), new Type[] { typeof(IHello)});
GenerateHelloMethod(typeBuilder);
Type type = typeBuilder.BuildType();
return Activator.CreateInstance(type) as IHello;
}
protected static void GenerateHelloMethod(EasyType tBuilder)
{
Type strType = typeof(string);
MethodInfo strConcat = typeof(string).GetMethod("Concat", new Type[] { strType, strType });
EasyMethod method = tBuilder.CreateMethod("GetString",
MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot,
new ReturnReferenceExpression(strType), strType);
LocalReference temp_local = method.CodeBuilder.DeclareLocal(strType);
AssignStatement stmtAssign = new AssignStatement(temp_local, new FixedReference("Hello ").ToExpression());
method.CodeBuilder.AddStatement(stmtAssign);
MethodInvocationExpression invokExpress = new MethodInvocationExpression(temp_local, strConcat, method.Arguments[0].ToExpression());
stmtAssign = new AssignStatement(temp_local, invokExpress);
method.CodeBuilder.AddStatement(stmtAssign);
method.CodeBuilder.AddStatement(new ReturnStatement(temp_local));
}
}
场景的实现:
IHello hello = MyGenerator.GenerateHello();
MessageBox.Show(hello.GetString());
当然上面的例子没有什么实用价值,只是为了说明如何利用DynamicProxy库进行二次开发,起一个抛砖引玉的作用。