AOP

    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>;
        }
    }
相關文章
相關標籤/搜索