1. 程式人生 > >面向切面程式設計(AOP)

面向切面程式設計(AOP)

結合設計模式,通過程式碼理解面向切面程式設計

通過,結構型設計模式,裝飾器模式來實現AOP

 /// <summary>
    /// 裝飾器模式實現靜態代理
    /// AOP 在方法前後增加自定義的方法
    /// </summary>
    public class DecoratorAOP
    {
        public static void Show()
        {
            User user = new User()
            {
                Name = "Eleven",
                Password 
= "123123123123" }; //直接呼叫 IUserProcessor processor = new UserProcessor(); processor.RegUser(user); Console.WriteLine("***************"); //通過裝飾器模式,在方法執行前後新增功能 processor = new UserProcessorDecorator(processor); processor.RegUser(user); }
public interface IUserProcessor { void RegUser(User user); } public class UserProcessor : IUserProcessor { public void RegUser(User user) { Console.WriteLine("使用者已註冊。Name:{0},PassWord:{1}", user.Name, user.Password); } }
/// <summary> /// 裝飾器的模式去提供一個AOP功能 /// </summary> public class UserProcessorDecorator : IUserProcessor { private IUserProcessor _UserProcessor { get; set; } public UserProcessorDecorator(IUserProcessor userprocessor) { this._UserProcessor = userprocessor; } public void RegUser(User user) { BeforeProceed(user); this._UserProcessor.RegUser(user); AfterProceed(user); } /// <summary> /// 業務邏輯之前 /// </summary> /// <param name="user"></param> private void BeforeProceed(User user) { Console.WriteLine("方法執行前"); } /// <summary> /// 業務邏輯之後 /// </summary> /// <param name="user"></param> private void AfterProceed(User user) { Console.WriteLine("方法執行後"); } } }

通過,結構型設計模式,代理模式來實現AOP

   /// <summary>
    /// 代理模式實現靜態代理
    /// AOP 在方法前後增加自定義的方法
    /// </summary>
    public class ProxyAOP
    {
        public static void Show()
        {
            User user = new User()
            {
                Name = "Eleven",
                Password = "123123123123"
            };
            IUserProcessor processor = new UserProcessor();
            //直接呼叫方法
            processor.RegUser(user);
            Console.WriteLine("***************");
            //實現AOP,在執行前後加其他方法
            processor = new ProxyUserProcessor();
            processor.RegUser(user);
        }

        public interface IUserProcessor
        {
            void RegUser(User user);
        }
        public class UserProcessor : IUserProcessor
        {
            public void RegUser(User user)
            {
                Console.WriteLine("使用者已註冊。Name:{0},PassWord:{1}", user.Name, user.Password);
            }
        }

        /// <summary>
        /// 代理模式去提供一個AOP功能
        /// </summary>
        public class ProxyUserProcessor : IUserProcessor
        {
            private IUserProcessor _UserProcessor = new UserProcessor();

            public void RegUser(User user)
            {
                BeforeProceed(user);
                this._UserProcessor.RegUser(user);
                AfterProceed(user);
            }

            /// <summary>
            /// 業務邏輯之前
            /// </summary>
            /// <param name="user"></param>
            private void BeforeProceed(User user)
            {
                Console.WriteLine("方法執行前");
            }
            /// <summary>
            /// 業務邏輯之後
            /// </summary>
            /// <param name="user"></param>
            private void AfterProceed(User user)
            {
                Console.WriteLine("方法執行後");
            }
        }

    }

通過Unity實現AOP,配置太複雜就不貼了。。。就一個實現類的程式碼,可以用於新增方法的日誌,異常處理,便於發現問題,不用挨個方法+Log.Info()了,通過Unity(IOC)建立的物件都能用

 public class LogBeforeBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("LogBeforeBehavior");
            Console.WriteLine(input.MethodBase.Name);
            foreach (var item in input.Inputs)
            {
                Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
                //反射&序列化獲取更多資訊
            }
            return getNext().Invoke(input, getNext);//
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }

 再加一個Unity建立物件和呼叫的程式碼吧,NuGet新增Unity的引用

public class UnityConfigAOP
    {
        public static void Show()
        {
            User user = new User()
            {
                Name = "Eleven",
                Password = "12345678934534643"
            };
             //這個是程式碼塊,好神奇的呦
            {
                //配置UnityContainer
                IUnityContainer container = new UnityContainer();
                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
                configSection.Configure(container, "aopContainer");

                IUserProcessor processor = container.Resolve<IUserProcessor>();
                processor.RegUser(user);

            }
        }
    }