castle之动态代理
动态代理 DynamicProxy,这里说的动态代理是直接使用Castle.net 中提供的,并非自己实现的,因为别人写的很好,拿着用就行了。
动态代理的工作模式:
一般我们获取一个类型的实例都是通过 new 关键字,例如 var c = new Class1(); 通过动态代理的话,我们获取一个实例是通过代理方法获取的,generator.CreateClassProxy(type, interceptor); 其中Type是要代理的类型,也就是Class1(); interceptor则是实际执行代理的拦截器。
为什么要用动态代理:
简单的说,例如我Class1与Class2都有自己的方法,我现在想给这两给类的每个方法都添加一个日志操作,如果不通过代理我们怎么做呢?每个函数开始增加一句Log.Enter();结束的时候增加一个Log.Exit(); 通过动态代理,我们可以增加一个拦截器,拦截器中,可以先执行Log.Enter();然后执行实际操作,最后在执行Log.Exit(); 这样我们就不需要去修改 Class1与Class2两个类。说白了就是为了符合OCP.
实现
1 public interface ISaySomething 2 { 3 void sayHK(); 4 } 5 6 public class Say : ISaySomething 7 { 8 public virtual void sayHK() 9 { 10 Console.WriteLine("hk"); 11 } 12 }
这个方法一定要用虚方法,因为会被代理类重写。
1 public class SayInterceptorProxy : IInterceptor 2 { 3 string _user; 4 public SayInterceptorProxy(string user) 5 { 6 this._user = user; 7 } 8 9 public void Intercept(IInvocation invocation) 10 { 11 if (_user == "hk") 12 { 13 beforeDoSomething(); 14 invocation.Proceed(); 15 afterDoSomething() 16 } 17 else 18 { 19 Console.WriteLine("{0}没有权限执行", _user); 20 } 21 } 22 }
这个是代理类,必须要继承 IInterceptor 接口 在执行你的逻辑方法之前或者之后,你都可以加上你自己的逻辑。其中 invocation 里面放的是代理方法的所有详细信息。
1 public void test() 2 { 3 ProxyGenerator proxyGenerator = new ProxyGenerator(); 4 var handle = new SayInterceptorProxy[] { new SayInterceptorProxy("wy") }; 5 ISaySomething iSay = proxyGenerator.CreateClassProxy<Say>(handle); 6 iSay.sayHK(); 7 }
这是调用执行过程。