闲来无事,做了一个AOP示例,此示例只能捕获方法调用事件,无法动态阻止方法调用的执行。因为取消后构造返回值成了难题,返回null貌似会报错。如果不需要这个功能,其实还是很完美的。
缺点是没有以接口方式实现,使用类必须继承ContextBoundObject。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Messaging; namespace Csharp实现AOP方法拦截 { #region AOP Helper public class MyApoAspect : IMessageSink { private IMessageSink _NextSink = null; private IMyAopMethodFilter _MethodFilter; internal MyApoAspect(IMessageSink msgSink, IMyAopMethodFilter methodFilter) { _NextSink = msgSink; _MethodFilter = methodFilter; } public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { IMessage message = this.SyncProcessMessage(msg); replySink.SyncProcessMessage(message); return null; } public IMessageSink NextSink { get { return _NextSink; } } public IMessage SyncProcessMessage(IMessage msg) { var cancel = false; _MethodFilter.PreAopMethodFilter(msg,ref cancel); if (cancel) { //此处不知如何返回 return null; } IMessage returnMethod = _NextSink.SyncProcessMessage(msg); _MethodFilter.PostAopMethodFilter(msg); return returnMethod; } } public class MyAopProperty: IContextProperty, IContributeObjectSink { private IMyAopMethodFilter _MethodFilter; public MyAopProperty(IMyAopMethodFilter methodFilter) { _MethodFilter = methodFilter; } public void Freeze(Context newContext) { } public bool IsNewContextOK(Context newCtx) { return true; } public string Name { get { return "MyAopProperty"; } } public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink) { return new MyApoAspect(nextSink, _MethodFilter); } } [AttributeUsage(AttributeTargets.Class)] public class MyAopAttribute : ContextAttribute, IMyAopMethodFilter { private IMyAopMethodFilter _MethodFilter; public MyAopAttribute() : base("MyAopAttribute") { _MethodFilter = this; } public override void GetPropertiesForNewContext(IConstructionCallMessage ccm) { ccm.ContextProperties.Add(new MyAopProperty(_MethodFilter)); } protected virtual void OnPreAopMethodFilter(IMessage msg, ref bool Cancel) { throw new NotImplementedException(); } protected virtual void OnPostAopMethodFilter(IMessage msg) { throw new NotImplementedException(); } public void PreAopMethodFilter(IMessage msg ,ref bool Cancel) { this.OnPreAopMethodFilter(msg,ref Cancel); } public void PostAopMethodFilter(IMessage msg) { this.OnPostAopMethodFilter(msg); } } public interface IMyAopMethodFilter { void PreAopMethodFilter(IMessage msg, ref bool Cancel); void PostAopMethodFilter(IMessage msg); } #endregion #region AOP Demo public class Class1AopAttribute : MyAopAttribute { protected override void OnPreAopMethodFilter(IMessage msg, ref bool Cancel) { IMethodMessage call = msg as IMethodMessage; Type type = Type.GetType(call.TypeName); string callStr = type.Name + "." + call.MethodName; var args = call.Args; Console.WriteLine("在执行前拦截到" + callStr); } protected override void OnPostAopMethodFilter(IMessage msg) { IMethodMessage call = msg as IMethodMessage; Type type = Type.GetType(call.TypeName); string callStr = type.Name + "." + call.MethodName; var args = call.Args; Console.WriteLine("在执行后拦截到" + callStr); } } [Class1AopAttribute()] public class Class1:ContextBoundObject { public int A { get; set; } public int B(ref int p) { p++; return p + 1; } } class Program { static void Main(string[] args) { Class1 c1 = new Class1(); c1.A = 2; int p = 0; c1.B(ref p); Console.ReadLine(); } } #endregion }