C#方法過濾器


方法過濾器

使用Emit和注解屬性Attribute實現

使用方式

1. 自定義方法過濾器

可分別定義方法執行前過濾器, 方法執行結束過濾器, 方法異常過濾器

  • 執行前過濾器繼承 ExecutingFilterAttribute 抽象類, 實現 Execute 抽象方法, 參數 parameters 為運行時攔截方法的參數列表

      /// <summary>
      /// 自定義執行前過濾器
      /// </summary>
      public class CustomExecutingFilterAttribute : ExecutingFilterAttribute
      {
          public string Name { get; set; }
    
          public override void Execute(MethodParameters[] parameters)
          {
              Console.WriteLine("=====================================================================");
              if (parameters != null)
                  Console.WriteLine($"執行前過濾器:{nameof(CustomExecutingFilterAttribute)}, Data:{this.Name}, Param:{string.Join(", ", parameters?.Select(p => p.ToString()))}");
              else
                  Console.WriteLine($"執行前過濾器:{nameof(CustomExecutingFilterAttribute)}, Data:{this.Name}");
          }
      }
    
  • 執行后過濾器繼承 ExecutedFilterAttribute 抽象類, 實現 Execute 抽象方法,其中泛型參數 returned 為攔截方法返回值, 對於無返回值的方法(void),此參數默認為數字 0

      /// <summary>
      /// 自定義執行后過濾器
      /// </summary>
      public class CustomExecutedFilterAttribute : ExecutedFilterAttribute
      {
          public override void Execute<TReturn>(MethodParameters[] parameters, TReturn returned)
          {
              if (parameters != null)
                  Console.WriteLine($"執行后過濾器:{nameof(CustomExecutedFilterAttribute)},Param:{string.Join(", ", parameters?.Select(p => p.ToString()))}, Return:{returned}");
              else
                  Console.WriteLine($"執行后過濾器:{nameof(CustomExecutedFilterAttribute)},Return:{returned}");
              Console.WriteLine("=====================================================================\r\n");
          }
      }
    
  • 異常過濾器繼承 ErrorFilterAttribute 抽象類, 實現 Execute 抽象方法, 其中參數 ex 為攔截方法拋出的未處理異常

      /// <summary>
      /// 自定義錯誤過濾器
      /// </summary>
      public class CustomErrorFilterAttribute : ErrorFilterAttribute
      {
          public override void Execute(MethodParameters[] parameters, Exception ex)
          {
              Console.ForegroundColor = ConsoleColor.Red;
              if (parameters != null)
                  Console.WriteLine($"異常過濾器:{nameof(CustomErrorFilterAttribute)}, Param:{string.Join(", ", parameters?.Select(p => p.ToString()))},Exception:{ex}");
              else
                  Console.WriteLine($"異常過濾器:{nameof(CustomErrorFilterAttribute)}, Exception:{ex}");
              Console.ResetColor();
          }
      }
    

2. 定義接口

    public interface IRepository
    {
        void Add<T>(T entity);

        void Remove<T>(T entity);

        void Update<T>(T entity, Func<T, bool> predicate);
    }

3. 定義接口實現類, 並在攔截方法上運用自定義過濾器

public class Repository : IRepository
{
    private List<string> list = new List<string>();

    //運用過濾器
    [CustomExecutingFilter]
    [CustomExecutedFilter]
    [CustomErrorFilter]
    public void Add<T>(T entity)
    {
        list.Add(entity.ToString());
        Console.WriteLine($"Added: Count-{list.Count}");
    }

    //運用過濾器
    [CustomExecutingFilter]
    [CustomExecutedFilter]
    [CustomErrorFilter]
    public void Remove<T>(T entity)
    {
        list.Remove(entity.ToString());
        Console.WriteLine($"Removed: Count-{list.Count}");
    }

    //運用過濾器
    [CustomExecutingFilter]
    [CustomExecutedFilter]
    [CustomErrorFilter]
    public void Update<T>(T entity, Func<T, bool> predicate)
    {
        var item = list.FirstOrDefault(p => predicate(entity));
        if (item == null)
            throw new Exception("列表中不存在更新的項");
        list.Remove(item);
        list.Add(entity.ToString());
    }
}

4. 調用

    //實例化接口實現類
    var repo = new Repository();
    //動態生成代理
    var repoProxy = EmitGenerator<IRepository>.GenerateProxy(repo);

    //使用代理調用方法
    repoProxy.Add("Hello");
    repoProxy.Add("World");
    repoProxy.Remove("World");
    repoProxy.Update("A,ning", p => p == "World");   //將會拋出列表中不存在項異常

5. 運行結果

Github:https://github.com/waning1995/Filter


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM