在.net实现AOP

本文通过一个简单的例子实现静态AOP.改例子主要实现客户的增删改查,突然有一天你的老板需要在程序上跟踪每个方法操作的运行日志。

主要分为5个步骤。

第一步:创建接口IRepository<T>,代码定义如下:

    public interface IRepository<T>
    {
      void Add(T entity);
      void Delete(T entity);
      void Update(T entity);
      IEnumerable<T> GetAll();
      T GetById(int id);
    }

第2步: 创建Repository<T>类,实现代码IRepository<T>,代码如下:

    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步,用Repository<T>实现Customer 的增删改查,Customer 定义如下:

    public class Customer
    {
      public int Id { get; set; }
      public string Name { get; set; }
      public string Address { get; set; }
    }

第4步,在控制台程序,运行,代码看起来如下:

    static void Main(string[] args)
    {
      Console.WriteLine("***\r\n Begin program - no logging\r\n");
      IRepository<Customer> customerRepository =new Repository<Customer>();
      var customer = new Customer
      {
        Id = 1,
        Name = "Customer 1",
        Address = "Address 1"
      };
      customerRepository.Add(customer);
      customerRepository.Update(customer);
      customerRepository.Delete(customer);
      Console.WriteLine("\r\nEnd program - no logging\r\n***");
      Console.ReadLine();
    }

按F5运行,运行结果如下图:

现在假如你的老板,需要在类中增加日志功能,你可以新建一个LoggerRepository<T>类,让他同样实现IRepository<T>,代码如下:

    public class LoggerRepository<T> : IRepository<T>
    {
      private readonly IRepository<T> _decorated;
      public LoggerRepository(IRepository<T> decorated)
      {
            _decorated = decorated;
      }
      private void Log(string msg, object arg = null)
      {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine(msg, arg);
        Console.ResetColor();
       }
      public void Add(T entity)
      {
        Log("In decorator - Before Adding {0}", entity);
        _decorated.Add(entity);
        Log("In decorator - After Adding {0}", entity);
      }
      public void Delete(T entity)
      {
        Log("In decorator - Before Deleting {0}", entity);
        _decorated.Delete(entity);
        Log("In decorator - After Deleting {0}", entity);
      }
      public void Update(T entity)
      {
        Log("In decorator - Before Updating {0}", entity);
        _decorated.Update(entity);
        Log("In decorator - After Updating {0}", entity);
      }
      public IEnumerable<T> GetAll()
      {
        Log("In decorator - Before Getting Entities");
        var result = _decorated.GetAll();
        Log("In decorator - After Getting Entities");
        return result;
      }
      public T GetById(int id)
      {
        Log("In decorator - Before Getting Entity {0}", id);
        var result = _decorated.GetById(id);
        Log("In decorator - After Getting Entity {0}", id);
        return result;
      }
    }

 

这个新类,已经包装了包装类,实现日志记录功能,现在需要做小的改动,代码实现如下:

 

static void Main(string[] args)
    {
      Console.WriteLine("***\r\n Begin program - logging with decorator\r\n");
      // IRepository<Customer> customerRepository =
      //   new Repository<Customer>();
      IRepository<Customer> customerRepository =
    new LoggerRepository<Customer>(new Repository<Customer>());
      var customer = new Customer
      {
        Id = 1,
        Name = "Customer 1",
        Address = "Address 1"
      };
      customerRepository.Add(customer);
      customerRepository.Update(customer);
      customerRepository.Delete(customer);
      Console.WriteLine("\r\nEnd program - logging with decorator\r\n***");
      Console.ReadLine();
    }

 

继续运行,运行结果如下:

 

到此为止,你可能会想:OK,这个想法是好的,但它仍然需要做很多工作:我必须实现所有的类和添加方面的所有方法。这将是难以维护。

有另一种方式去做吗?.net框架,您可以使用反射来得到所有方法和执行它们。基类库(BCL)甚至有RealProxy类(bit.ly/18MfxWo),为你实现。

答案:是的有的就是我们所讲的动态代理实现AOP; 我们将在下一节讲

AOP参考

本文翻译自 :https://msdn.microsoft.com/en-us/magazine/dn574804.aspx(面向切面编程)

最新文章

  1. C#控制台项目更改运行文件
  2. link和@import导入css文件的区别
  3. git免密码pull,push
  4. StreamReader和StreamWrite和FileStream区别和用法
  5. ADS报错 Warning&#160;:&#160;L6301W:Could&#160;not&#160;find&#160;file&#160;C:\Program&#160;Files&#160;.&#160;Error&#160;:&#160;L6218&#160;:&#160;Undefined&#160;symbol&#160;......
  6. 【转载】分析商品日均销量(DMS)对促销商品选择的意义
  7. HTTP长连接实现“服务器推”的技术
  8. double 型变量的输入输出标准格式
  9. POJ 2115 C Looooops(扩展欧几里得应用)
  10. Activity与Activity之间的传值
  11. 2.Servlet 请求、响应及重定向
  12. entityVo对象与entity对象
  13. JVM笔记——编译期的优化
  14. ChunkDisappearImage-一个以矩形为单位的图片消失分解效果
  15. dialog里屏蔽ESC和回车
  16. adb连接不上手机的解决方案
  17. CookieUtils工具类
  18. linux下Ctrl命令组合
  19. static使用实例
  20. mysql的with rollup

热门文章

  1. JavaEE 技术体系
  2. C++(十八) — 内存模式、堆和栈
  3. XML的两种解析方式
  4. SpringCloud教程 | 第七篇: 高可用的分布式配置中心(Spring Cloud Config)
  5. mcake活动维护常见问题记录【wap端】 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
  6. 剑指offer--36.整数中1出现的次数(从1到n整数中1出现的次数)
  7. 用 WEKA 进行数据挖掘 ——第一章:简介
  8. HAWQ取代传统数仓实践(十二)——维度表技术之分段维度
  9. verilog case 语句合并问题
  10. Django初体验——搭建简易blog