zoukankan      html  css  js  c++  java
  • .NET 简易方法拦截器

            伟大的无产阶级Willaim曾说过:"无论你觉得自己多么的了不起,也永远有人比你更强"。对,我说过!我就是william。

           今天想记录一下在项目中遇到的一个比较有意思的东西,异常拦截器(也不能完全说只是异常拦截,准确的说应该叫方法拦截),那有的人可能会说,异常拦截器不就是用Try……Catch就好了吗?没错,Try……Catch是能拦截到异常。如果只是简单拦截下,这种方法简单可行。但是我们如果扩展下,所有的异常都要统一处理,如果你是架构师,你的团队需要你提供一个公共的异常拦截处理组件,你会怎么处理。

            其实在做这个demo之前,我也是想了很多种处理方式,例如在方法前加特性头使用AOP的方式,这种看的比较高大上,也需要配置大量config文件,比较复杂。也不适合我的项目现状(实则是懒,由于框架已经基本形成,采用这种方式需要改动大量的已经完成的框架代码,而且时间紧迫),所以放弃了。开始需求给到我时,一时之间无从下手,在网上搜罗很多处理方式,但大多数都是采用AOP加特性头。当然我也这个demo也是借助于博客园中各位大神的经验。站在巨人的肩膀上,我可以看得更远!谢谢博客园的各位博主!矫情的话不多说了直接开始我的代码之旅。

           首先我们看看效果图,俗话说没图说个J8,有图有文的才是好博文。

           

                                            (这是一张执行正常的截图)

                  

                                                 (这是一张执行带有异常的截图)

             

                      (demo的结构图,只是简单的模拟)

            解释一下工程结构图每隔类文件的作用。其中红框标记的是本次的重要组件,你的拦截器中需要用他中间的接口。Castle.Core我们可以在NuGet中进行安装。

           1.【MyIntercept.cs

            这个文件就是自定义的拦截器。代码很简单。        

     1 using Castle.DynamicProxy; //必须的
     2 
     3 
     4 public class MyIntercept : IInterceptor //需要实现这个接口(翻译拦截)
     5 {
     6     public void Intercept(IInvocation invocation)
     7     {
     8        Console.WriteLine("【进入拦截器】");
     9        MethodInfo method = invocation.GetConcreteMethod();//得到被拦截的方法
    10             var parameter=invocation.Arguments[0].ToString();//获取被拦截的方法参数
    11             if (!invocation.MethodInvocationTarget.IsAbstract)
    12             {
    13                 Console.WriteLine("【被拦截的方法执行前】"+method.Name+"的参数"+ parameter);
    14                
    15                 try
    16                 {
    17                     invocation.Proceed();
    18                 }
    19                 catch (Exception ex)
    20                 {
    21 
    22                     Console.WriteLine("【拦截到异常】"+ex.Message);
    23                 }
    24                 Console.WriteLine("【被拦截的方法执结果】"+invocation.ReturnValue);
    25                
    26             }
    27             Console.WriteLine("【被拦截的方法执完毕】");
    28         }
    29     }
    View Code

            2.ITestIntercept.cs

           定义一个接口,接口中定义需要实现的方法,也就是需要被拦截的方法     

    1 public interface ITestIntercept
    2  {
    3         string Test(string p);
    4 }
    View Code

           3.【TestIntercept.cs

            实现上面的接口     

    1  public class TestIntercept : ITestIntercept
    2 {
    3     public string Test(string p)
    4     {
    5         throw new Exception("异常了"); //演示抛出异常,拦截器是否能捕捉到异常信息
    6             //return p;
    7     }
    8 }
    View Code

          基本的异常拦截准备工作已经完毕,我们看看如何使用拦截器对方法进行拦截。

     1 using Castle.DynamicProxy; //必须的
     2 class Program
     3     {
     4         static void Main(string[] args)
     5         {
     6             MyIntercept myIntercept = new MyIntercept();//实例化拦截器
     7             ProxyGenerator proxy = new ProxyGenerator(); //实例化代理
     8             ITestIntercept intercept = proxy.CreateInterfaceProxyWithTarget<ITestIntercept>(new TestIntercept(),myIntercept);
     9             intercept.Test("william");
    10             Console.ReadLine();
    11         }
    12     }
    View Code

    好了,一个简单的方法拦截demo完成,他可以应用到很多场景,比如:权限验证,异常统计等等。

    遗留问题,有兴趣的同学可以试试:

    1.如果接口中有多个方法,拦截器会全部拦截吗?

    2.ProxyGenerator,我才用的是CreateInterfaceProxyWithTarget对接口和实现类进行mapping。是否还有其他的方式进行mapping工作,例如配置文件?

    3.本次demo中采用的是实现接口的方式对方法进行拦截,如果不用接口,拦截器是否会起作用。因为我发现在ProxyGenerator中有个CreateClassProxyWithTarget()函数。大家可以试试。

           

                                  

  • 相关阅读:
    四叶草社交平台——十天冲刺(7)
    四叶草社交平台——十天冲刺(6)
    多表查询
    单表 查询
    django模板的导入
    2019-3-1
    DJANGO 28
    路由
    Django项目的创建与介绍
    数据传输方式
  • 原文地址:https://www.cnblogs.com/stoneWl/p/9076531.html
Copyright © 2011-2022 走看看