class Program { static void Main(string[] args) { Console.Title = ""; Console.WriteLine(new Calc().add(1, 0)); Console.WriteLine(new Calc().add(2, 3)); Console.WriteLine(new Calc().add(1, 1)); Console.ReadKey(true); } } [AOP] public class Calc : ContextBoundObject { [AOPMethod] public int add(int a, int b) { return a + b; } }
/// <summary> /// AOP方法處理類,實現了IMessageSink接口 /// </summary> public sealed class MyAopHandler : IMessageSink { /// <summary> /// 下一個接收器 /// </summary> public IMessageSink NextSink { get; private set; } public MyAopHandler(IMessageSink nextSink) { this.NextSink = nextSink; } /// <summary> /// 同步處理方法 /// </summary> /// <param name="msg"></param> /// <returns></returns> public IMessage SyncProcessMessage(IMessage msg) { //方法調用消息接口 var call = msg as IMethodCallMessage; //只攔截指定方法,其它方法原樣釋放 if (call == null || (Attribute.GetCustomAttribute(call.MethodBase, typeof(AOPMethodAttribute))) == null || call.MethodName != "add") return NextSink.SyncProcessMessage(msg); //判斷第2個參數,若是是0,則強行返回100,不調用方法了 if (((int)call.InArgs[1]) == 0) return new ReturnMessage(100, call.Args, call.ArgCount, call.LogicalCallContext, call); //判斷第2個參數,若是是1,則參數強行改成50(失敗了) //if (((int)call.InArgs[1]) == 1) call = new MyCall(call, call.Args[0], 50);//方法1 失敗了 //if (((int)call.InArgs[1]) == 1) call.MethodBase.Invoke(GetUnwrappedServer(), new object[] { call.Args[0], 50 });//方法2 (沒法湊夠參數) //執行本來的方法 也就是執行add方法 var retMsg = NextSink.SyncProcessMessage(call); //判斷返回值,若是是5,則強行改成500 if (((int)(retMsg as IMethodReturnMessage).ReturnValue) == 5) return new ReturnMessage(500, call.Args, call.ArgCount, call.LogicalCallContext, call); return retMsg; } /// <summary> /// 異步處理方法(暫不處理) /// </summary> /// <param name="msg"></param> /// <param name="replySink"></param> /// <returns></returns> public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) => null; } /// <summary> /// 貼在方法上的標籤 /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class AOPMethodAttribute : Attribute { } /// <summary> /// 貼在類上的標籤 /// </summary> [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public class AOPAttribute : ContextAttribute, IContributeObjectSink { public AOPAttribute() : base("AOP") { } /// <summary> /// 實現消息接收器接口 /// </summary> /// <param name="obj"></param> /// <param name="next"></param> /// <returns></returns> public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next) => new MyAopHandler(next); }
*************************第二種 這種更好理解一點app
https://msdn.microsoft.com/zh-cn/library/dn574804.aspx異步
執行操做的先後都打印日誌進行記錄ide
1.接口this
public interface IRepository<T> { void Add(T entity); void Delete(T entity); void Update(T entity); IEnumerable<T> GetAll(); T GetById(int id); }
2.實現接口spa
public class Repository<T>: IRepository<T> { public void Add(T entity) { Console.WriteLine("Adding {0}", entity); } public void Delete(T entity) { Console.WriteLine("Deleting {0}", entity); } public void Update(T entity) { Console.WriteLine("Updating {0}", entity); } public IEnumerable<T> GetAll() { Console.WriteLine("Getting entities"); return null; } public T GetById(int id) { Console.WriteLine("Getting entity {0}", id); return default(T); } }
3.使用 RealProxy 建立動態代理代理
public class DynamicProxy<T>: RealProxy { //本來的對象 private readonly T _decorated; public DynamicProxy(T decorated) : base(typeof(T)) { _decorated = decorated; } private void Log(string msg, object arg = null) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(msg, arg); Console.ResetColor(); } public override IMessage Invoke(IMessage msg) { var methodCall = msg as IMethodCallMessage; var methodInfo = methodCall.MethodBase as MethodInfo; //執行前打印日誌 Log("In Dynamic Proxy - Before executing '{0}'",methodCall.MethodName); try { //執行本來方法 var result = methodInfo.Invoke(_decorated, methodCall.InArgs); //執行後打印日誌 Log("In Dynamic Proxy - After executing '{0}' ",methodCall.MethodName); return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall); } catch (Exception e) { Log(string.Format("In Dynamic Proxy- Exception {0} executing '{1}'", e),methodCall.MethodName); return new ReturnMessage(e, methodCall); } } }
4.要使用通過修飾的存儲庫,您必須使用 GetTransparentProxy 方法,此方法將返回 IRepository<Customer> 的實例。所調用的此實例的每一個方法都將經歷該代理的 Invoke 方法。爲了方便實現此過程,您能夠建立一個 Factory 類來建立代理並返回存儲庫的實例日誌
public class RepositoryFactory { public static IRepository<T> Create<T>() { var repository = new Repository<T>(); var dynamicProxy = new DynamicProxy<IRepository<T>>(repository); return dynamicProxy.GetTransparentProxy() as IRepository<T>; } }