轻量级AOP的另一种实现(100%开源)
说到轻量级,本人先发声明,本人不对那些大型或重型的框架,有任何敌对或排斥,只是更喜欢轻量的框架,使用起来清爽,不需要太多的配置。就像工作流之列的东西,本人就见过一个非常好的框架,你可以这样声明一个包含驳回,且一人通过全局通过的简单工作流。
????一般AOP有三中实现方式:代理,织入,继承ContextBoundObject。(更全的讲解请看,AOP in .NET和现有AOP解决方案收集)
????此AOP就是使用代理方式来实现的,所以在Aop.Proxy命名空间下。就5个代码文件,一个公开接口(IAspectAdvice),两个内部类(AspectManager和AspectProxy),一个无任何抽象方法的抽象类(AspectOrientedObject),一个特性类(AspectOrientedAttribute),外部可见对象三个:一个接口,一个抽象类和一个特性类。
??? 先看接口:
?><Monk> <Aop> <ProxyAop> <!--type是指要拦截的对象类型,providertype是指提供拦截方法的类型, 两者个格式是"assembly,classname" methodname指要拦截的方法名 --> <Aspect type="Test.exe,Test.calculate" providertype="Test.exe,Test.Aspect" methodname="Add"/> <Aspect type="TestFrm.exe,TestFrm.calculate" providertype="TestFrm.exe,TestFrm.Aspect" methodname="Add"/> </ProxyAop> </Aop></Monk>AspectManager:
internal static class AspectManager { static AspectManager() { try { XmlDocument doc = new XmlDocument(); doc.Load("Monk.xml"); XmlNodeList list = doc.SelectNodes("/Monk/Aop/ProxyAop/Aspect"); foreach (XmlNode node in list) { try { string type = node.Attributes["type"].Value + "," + node.Attributes["methodname"].Value; string providertype = node.Attributes["providertype"].Value; int index = providertype.IndexOf(','); IAspectAdvice advice = Assembly.LoadFrom(providertype.Substring(0, index)) .CreateInstance(providertype.Substring(index + 1)) as IAspectAdvice; if (cache.ContainsKey(type)) { cache[type].Add(advice); } else { cache.Add(type, new List<IAspectAdvice>() { advice}); } } catch { } } } catch { } } //缓存 private static Dictionary<string, List<IAspectAdvice>> cache = new Dictionary<string, List<IAspectAdvice>>(); //获取通知 public static IAspectAdvice[] FindAspect(Type t, IMethodMessage msg) { if (msg == null) { return null; } string s = t.Assembly.ManifestModule.Name + "," + t.FullName + "," + msg.MethodName; if (cache.ContainsKey(s)) { return cache[s].ToArray(); } return null; } }
??? 配置文件和AspectManager就不讲了,就是读取配置文件,然后利用反射实例化对象。
??? 总结一下吧:
??? 其实就是这样的,利用对象的代理来对对象进行操作,然后我们来操作这个代理,从而达到操作对象的目的。?