Castle AOP 系列(二):对接口方法调用的拦截
2008-07-10 11:59
309 查看
Castle中有一个扩展的DynamicProxy程序集(DynamicProxy2),在这个程序集中,提供了对接口方法做动态拦截的能力。相比于对类方法的拦截,对接口方法的拦截为我们的架构设计方面提供了更大的自由度。在这里先罗列一些简单的代码,大家可以从这些代码中先思考一下接口方法的动态拦截可以应用于哪些方面,在以后的章节中,我们会深入的讨论具体的应用层面,其实这个在我们Mussel通信层的插件的实施中,于客户端产生服务端接口的Proxy起到了决定性的作用。先看代码:
接口的定义
namespace Unit7
{
public interface IPerson
{
void SayHello();
void SayName(string name);
string GotoSchool(string schoolName, string grade, string classes);
}
}
方法拦截器的实现
using System;
using System.Reflection;
using Castle.Core.Interceptor;
namespace Unit7
{
public class SimpleInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Current MethodName:{0}", invocation.Method.Name);
string signature = string.Empty;
//在这个循环中通过反射计算出方法签名
foreach(ParameterInfo info in invocation.Method.GetParameters())
{
string paramSignature =
string.Format("{0} {1}",
info.ParameterType.Name,
info.Name);
if (string.IsNullOrEmpty(signature))
signature = paramSignature;
else signature = signature + "," + paramSignature;
}
//输出方法签名
Console.WriteLine("Method Signature:{0} ({1})",
invocation.Method.ReturnType.Name,
signature);
//直接设置返回值为函数名称
invocation.ReturnValue = invocation.Method.Name;
}
}
}
调用的主程序
using System;
using Castle.DynamicProxy;
namespace Unit7
{
public class Program
{
private static int Main()
{
ProxyGenerator generator = new ProxyGenerator();
//采用默认的基类(Object)
IPerson person =
generator.CreateInterfaceProxyWithoutTarget<IPerson>
(new SimpleInterceptor());
DisplayMessage(person);
ProxyGenerator proxyGenerator = new ProxyGenerator();
ProxyGenerationOptions options = new ProxyGenerationOptions();
//改变接口对象的基类为MarshalByRefObject
options.BaseTypeForInterfaceProxy = typeof(MarshalByRefObject);
Console.WriteLine();
Console.WriteLine("=====================================");
IPerson person1 =
(IPerson) proxyGenerator.CreateInterfaceProxyWithoutTarget(
typeof (IPerson),
null, options,
new SimpleInterceptor());
DisplayMessage(person1);
Console.ReadLine();
return 0;
}
private static void DisplayMessage(IPerson person)
{
Console.WriteLine("Current BaseType:{0}", person.GetType().BaseType);
Console.WriteLine();
person.SayHello();
Console.WriteLine();
person.SayName("Roger");
Console.WriteLine();
Console.WriteLine(
"Return Value:{0}",
person.GotoSchool("华师附小", "三年级", "三班"));
}
}
}
上面的程序比较容易理解,大家可以自己试试。可以看到在这里我们没有对接口作任何实现,但是我们依然可以获取到接口的实例对象。并且在上面的实例中,我们 还演示了如何改变动态生成的接口实例对象的基类,这是一个非常有用的操作,在下一个章节中,我们就会看到它实际的应用,我们看看程序输出:
欢迎大家访问我的博客主站: http://www.rogertong.cn
点击下载源程序
接口的定义
namespace Unit7
{
public interface IPerson
{
void SayHello();
void SayName(string name);
string GotoSchool(string schoolName, string grade, string classes);
}
}
方法拦截器的实现
using System;
using System.Reflection;
using Castle.Core.Interceptor;
namespace Unit7
{
public class SimpleInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Current MethodName:{0}", invocation.Method.Name);
string signature = string.Empty;
//在这个循环中通过反射计算出方法签名
foreach(ParameterInfo info in invocation.Method.GetParameters())
{
string paramSignature =
string.Format("{0} {1}",
info.ParameterType.Name,
info.Name);
if (string.IsNullOrEmpty(signature))
signature = paramSignature;
else signature = signature + "," + paramSignature;
}
//输出方法签名
Console.WriteLine("Method Signature:{0} ({1})",
invocation.Method.ReturnType.Name,
signature);
//直接设置返回值为函数名称
invocation.ReturnValue = invocation.Method.Name;
}
}
}
调用的主程序
using System;
using Castle.DynamicProxy;
namespace Unit7
{
public class Program
{
private static int Main()
{
ProxyGenerator generator = new ProxyGenerator();
//采用默认的基类(Object)
IPerson person =
generator.CreateInterfaceProxyWithoutTarget<IPerson>
(new SimpleInterceptor());
DisplayMessage(person);
ProxyGenerator proxyGenerator = new ProxyGenerator();
ProxyGenerationOptions options = new ProxyGenerationOptions();
//改变接口对象的基类为MarshalByRefObject
options.BaseTypeForInterfaceProxy = typeof(MarshalByRefObject);
Console.WriteLine();
Console.WriteLine("=====================================");
IPerson person1 =
(IPerson) proxyGenerator.CreateInterfaceProxyWithoutTarget(
typeof (IPerson),
null, options,
new SimpleInterceptor());
DisplayMessage(person1);
Console.ReadLine();
return 0;
}
private static void DisplayMessage(IPerson person)
{
Console.WriteLine("Current BaseType:{0}", person.GetType().BaseType);
Console.WriteLine();
person.SayHello();
Console.WriteLine();
person.SayName("Roger");
Console.WriteLine();
Console.WriteLine(
"Return Value:{0}",
person.GotoSchool("华师附小", "三年级", "三班"));
}
}
}
上面的程序比较容易理解,大家可以自己试试。可以看到在这里我们没有对接口作任何实现,但是我们依然可以获取到接口的实例对象。并且在上面的实例中,我们 还演示了如何改变动态生成的接口实例对象的基类,这是一个非常有用的操作,在下一个章节中,我们就会看到它实际的应用,我们看看程序输出:
欢迎大家访问我的博客主站: http://www.rogertong.cn
点击下载源程序
相关文章推荐
- Castle AOP 系列(二):对接口方法调用的拦截(有源码)
- U811.1接口EAI系列之一-通用访问EAI方法--统一调用EAI公共方法--VB语言
- Castle AOP 系列(一):对类方法调用的拦截(有源码)
- Castle AOP 系列(一):对类方法调用的拦截
- Ajax调用restful接口传送Json格式数据的方法
- C语言调用C++库接口的方法概述
- IP地址查询接口及调用方法
- [Unity2d系列教程] 004.Unity如何调用ios的方法(SDK集成相关)
- 如何调用http接口通过get()/post()方法传参
- java调用webservice接口方法大全
- wp7模拟器开启不了,显示“被调用的对象已与其客户端断开连接”或者“接口”。并且提示有文件损坏的处理方法
- python基础----继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法
- MFC调用VLC接口在IPC控件显示视频,然后鼠标在视频上绘图解决方法
- static方法中调用接口,SpringContextUtil工具类实现
- C#调用VC DLL接口函数参数类型转换方法介绍
- java调用webservice接口方法
- php用curl调用接口方法,get和post两种方式
- IP地址查询接口及调用方法
- PHP 使用 curl_* 系列函数和 curl_multi_* 系列函数进行多接口调用时的性能对比
- Java 中接口为什么可以调用 toString 方法,接口中根本就没有 toString 方法?