VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C# AOP学习笔记(2)

public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { IMethodReturn methodReturn = getNext()(input, getNext); if (methodReturn.Exception == null) { Console.WriteLine("ExceptionHandler:没有异常"); } else { Console.WriteLine($"ExceptionHandler:出现异常:{methodReturn.Exception.Message}"); } return methodReturn; } } public class LogHandler : ICallHandler { public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { User user = input.Inputs[0] as User; string message = string.Format($"Name:{user.Name} Password:{user.Password}"); Console.WriteLine($"LogHandler:日志已记录。Message:{message}"); IMethodReturn methodReturn = getNext()(input, getNext); return methodReturn; } } public class UserHandler : ICallHandler { public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { User user = input.Inputs[0] as User; if (user.Password.Length < 10) { return input.CreateExceptionMethodReturn(new Exception("UserHandler:密码长度不能小于10位")); } //getNext()(input, getNext):委托后的委托,即多重委托。 IMethodReturn methodReturn = getNext()(input, getNext); return methodReturn; } } public class AfterLogHandler : ICallHandler { public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { IMethodReturn methodReturn = getNext()(input, getNext); Console.WriteLine($"AfterLogHandler:方法执行结果--{methodReturn.ReturnValue}"); Console.WriteLine("AfterLogHandler:方法执行后"); return methodReturn; } } #endregion 特性对应的行为 /// <summary> /// 运行测试 /// </summary> public static void Show() { User user = new User() { Name = "Hello", Password = "HelloWorld" }; IUnityContainer container = new UnityContainer(); //声明一个容器 container.AddNewExtension<Interception>() .RegisterType<IUserProcessor, UserProcessor>(new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>()); //显式拦截 IUserProcessor processor = container.Resolve<IUserProcessor>(); processor.RegUser(user); //调用 } }
复制代码

    3)调用:

复制代码
        static void Main(string[] args)
        {
            #region 使用EntLib\PIAB Unity实现动态代理(非配置)
            UnityAOP.Show();
            Console.Read();
            #endregion
        }
复制代码

    4)运行结果如下:

    3.2.4、使用EntLib\PIAB Unity实现AOP(带配置)

    1)继续在NuGet中安装Unity.Configuration、Unity.Interception.Configuration及Newtonsoft.Json。

    2)分别建立以下类:

复制代码
    /// <summary>
    /// 用户类
    /// </summary>
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
    }
复制代码
复制代码
    /// <summary>
    /// 用户注册接口
    /// </summary>
    public interface IUserProcessor
    {
        void RegUser(User user);
    }
复制代码
复制代码
    /// <summary>
    /// 用户注册接口实现类
    /// </summary>
    public class UserProcessor : IUserProcessor
    {
        public void RegUser(User user)
        {
            Console.WriteLine($"用户注册成功。Name:{user.Name} Password:{user.Password}");
        }
    }
复制代码
复制代码
    /// <summary>
    /// 使用EntLib\PIAB Unity实现动态代理(带配置)
    /// </summary>
    public class UnityConfigAOP
    {
        public static void Show()
        {
            User user = new User() { Name = "Hello", Password = "HelloWorld" };

            //配置UnityContainer
            IUnityContainer container = new UnityContainer();
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap
            {
                ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"UnityConfigAOP\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);
        }
    }
复制代码
复制代码
    /// <summary>
    /// 不需要特性
    /// </summary>
    public class ExceptionBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            IMethodReturn methodReturn = getNext()(input, getNext);

            Console.WriteLine("ExceptionBehavior");
            if (methodReturn.Exception == null)
            {
                Console.WriteLine("无异常");
            }
            else
            {
                Console.WriteLine($"异常:{methodReturn.Exception.Message}");
            }
            return methodReturn;
        }
    }
复制代码
复制代码
    /// <summary>
    /// 不需要特性
    /// </summary>
    public class CachingBehavior : IInterceptionBehavior
    {
        private static Dictionary<string, object> CachingBehaviorDictionary = new Dictionary<string, object>();

        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("CachingBehavior");
            string key = $"{input.MethodBase.Name}_{Newtonsoft.Json.JsonConvert.SerializeObject(input.Inputs)}";
            if (CachingBehaviorDictionary.ContainsKey(key))
            {
                return input.CreateMethodReturn(CachingBehaviorDictionary[key]);    //断路器,直接返回。
            }
            else
            {
                IMethodReturn result = getNext().Invoke(input, getNext);
                if (result.ReturnValue != null)
                    CachingBehaviorDictionary.Add(key, result.ReturnValue);
                return result;
            }
        }
    }
复制代码
复制代码
    /// <summary>
    /// 不需要特性
    /// </summary>
    public class PermissionBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("PermissionBehavior");
            Console.WriteLine(input.MethodBase.Name);
            foreach (var item in input.Inputs)
            {
                Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
                //反射&序列化获取更多信息
            }
            return getNext().Invoke(input, getNext);
        }
    }
复制代码
复制代码
    /// <summary>
    /// 不需要特性
    /// </summary>
    public class ParameterCheckBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            User user = input.Inputs[0] as User;    //可以不写死类型,反射+特性完成数据有效性监测。

            Console.WriteLine("ParameterCheckBehavior");
            if (user.Password.Length < 10)          //可以过滤一下敏感词
            {
                return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
            }
            else
            {
                return getNext().Invoke(input, getNext);
            }
        }
    }
复制代码
复制代码
    /// <summary>
    /// 不需要特性
    /// </summary>
    public class LogBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            IMethodReturn methodReturn = getNext()(input, getNext); //执行后面的全部动作

            Console.WriteLine("LogBehavior");
            Console.WriteLine(input.MethodBase.Name);
            foreach (var item in input.Inputs)
            {
                Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
                //反射&序列化获取更多信息
            }
            return methodReturn;
        }
    }
复制代码

    3)新建一个配置文件Unity.Config(本例代码是在UnityConfigAOP文件夹下),在其属性的复制到输出目录项下选择始终复制。

复制代码
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
    <containers>
      <container name="AOPContainer">
        <extension type="Interception"/>
        <!--注册匹配规则:前面是完整类型名称,后面是所在的dll名称。-->
        <register type="LinkTo.Test.ConsoleAop.UnityConfigAOP.IUserProcessor,LinkTo.Test.ConsoleAop" mapTo="LinkTo.Test.ConsoleAop.UnityConfigAOP.UserProcessor,LinkTo.Test.ConsoleAop">
          <interceptor type="InterfaceInterceptor"/>
          <!--拦截顺序为由上而下;配置会全部执行,除非遇到断路器等;建议异常处理包在最外层,即在最上面。-->
          <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.ExceptionBehavior, LinkTo.Test.ConsoleAop"/>
          <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.CachingBehavior, LinkTo.Test.ConsoleAop"/>
          <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.PermissionBehavior, LinkTo.Test.ConsoleAop"/>
          <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.ParameterCheckBehavior, LinkTo.Test.ConsoleAop"/>
          <interceptionBehavior type="LinkTo.Test.ConsoleAop.UnityConfigAOP.LogBehavior, LinkTo.Test.ConsoleAop"/>
        </register>
      </container>
    </containers>
  </unity>
</configuration>
复制代码

    4)调用:

复制代码
        static void Main(string[] args)
        {
            #region 使用EntLib\PIAB Unity实现动态代理(带配置)
            UnityConfigAOP.UnityConfigAOP.Show();
            Console.Read();
            #endregion
        }
复制代码

    5)运行结果如下:

    3.3、IL编织方式

    IL编织方式,可以使用PostSharp框架来做,但是由于Postsharp从2.0版本开始收费,此处不再作说明,有兴趣的话可以百度一下。 

 

    参考自:

    https://www.cnblogs.com/landeanfen/p/4782370.html

    https://www.cnblogs.com/artech/archive/2011/12/01/autointerception.html

    E神公开课代码


相关教程
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号