C#使用委託實現函式回撥,方法呼叫攔截
回撥方法、攔截方法定義
public class AopHelper { public static async Task<T> ExecuteGenericMethod<T>(Task<T> returnValue, Action<T> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { try { var result = await returnValue; callBackAction?.Invoke(result); return result; } catch (Exception ex) { exceptionAction?.Invoke(ex); return default; } finally { finallyAction?.Invoke(); } } public static object CallGenericMethod(IInvocation invocation, Action<object> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { return typeof(AopHelper) .GetMethod("ExecuteGenericMethod", BindingFlags.Public | BindingFlags.Static) .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) .Invoke(null, new object[] { invocation.ReturnValue, callBackAction, exceptionAction, finallyAction }); } }
下面是具體實現 方法執行完 回撥函式 異常函式 資源釋放函式
public class Test01 { // 任務方法:非同步執行某些操作 public static async Task<int> DoSomethingAsync(int a) { await Task.Delay(1000); // 模擬非同步操作 //Random rnd = new Random(); int number = a; if (number < 5) { throw new InvalidOperationException("發生了一個隨機異常!"); } return number; } // 主方法:呼叫 ExecuteGenericMethod<T> 並提供回撥和異常處理 public static async Task Main(int a) { // 呼叫 ExecuteGenericMethod 並處理任務的成功、異常和最終操作 int result = await ExecuteGenericMethod( DoSomethingAsync(a), success => Console.WriteLine($"成功執行,結果為: {success}"), // 成功回撥 ex => Console.WriteLine($"處理異常: {ex.Message}"), // 異常處理 () => Console.WriteLine("清理操作:無論是否成功都要執行的程式碼") // 最終執行 ); Console.WriteLine($"最終返回的結果: {result}"); } // 泛型方法:執行非同步任務並處理回撥、異常和清理操作 public static async Task<T> ExecuteGenericMethod<T>( Task<T> returnValue, Action<T> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { try { var result = await returnValue; callBackAction?.Invoke(result); return result; } catch (Exception ex) { exceptionAction?.Invoke(ex); return default; } finally { finallyAction?.Invoke(); } } }
public class Test02 { public static object CallGenericMethod(IInvocation invocation, Action<object> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { return typeof(AopHelpers) .GetMethod("ExecuteGenericMethod", BindingFlags.Public | BindingFlags.Static) .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) .Invoke(null, new object[] { invocation.ReturnValue, callBackAction, exceptionAction, finallyAction }); } public static async Task Main(int a) { AopHelpers aopHelper = new AopHelpers(); int s = await ExecuteGenericMethod<int>(aopHelper.DoSomethingAsync(a), success => aopHelper.CallBackAction(success), ex => aopHelper.ExceptionFunction01(ex), () => aopHelper.ActionFunction01(a)); Console.WriteLine(s); } public static async Task<T> ExecuteGenericMethod<T>(Task<T> returnValue, Action<T> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { try { var result = await returnValue; callBackAction?.Invoke(result); return result; } catch (Exception ex) { exceptionAction?.Invoke(ex); return default; } finally { finallyAction?.Invoke(); } } public async Task<int> DoSomethingAsync(int a) { if (a < 5) { throw new InvalidOperationException("發生了一個隨機異常!"); } Console.WriteLine("主方法執行完 a:" + a); //return Task.FromResult(a); 返回異常直接拋到最外層 return a + 2; } public Action<int> CallBackAction(int a) { Console.WriteLine("我是方法執行完的回撥函式 a:" + a); //return a => { a = a + 6; }; return a => a = a + 6; } public Action<Exception> ExceptionFunction01(Exception ex) { Console.WriteLine("方法執行報錯 值為:" + ex.Message); return ex => Console.WriteLine($"處理異常: {ex.Message}"); } public Action ActionFunction01(int a) { Console.WriteLine("資源使用完畢清空"); return () => a = 0; } }
下面是具體方法呼叫前的攔截 和引數校驗
public interface IMyService { Task<int> DoSomethingAsync(); } public class MyService : IMyService { public async Task<int> DoSomethingAsync() { await Task.Delay(100); // 模擬非同步操作 //return new List<int> {1,2,3 }; // 返回一些結果 return 1; // 返回一些結果 這裡是int型別會報異常 返回object正常 } } public static class IInvocationProgram { public static object CallGenericMethod(IInvocation invocation, Action<object> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { return typeof(IInvocationProgram) .GetMethod("ExecuteGenericMethod", BindingFlags.Public | BindingFlags.Static) .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) .Invoke(null, new object[] { invocation.ReturnValue, callBackAction, exceptionAction, finallyAction }); } public static T ExecuteGenericMethod<T>(Task<T> returnValue, Action<T> callBackAction, Action<Exception> exceptionAction, Action finallyAction) { try { // 模擬等待任務完成並返回結果 var result = returnValue.Result; callBackAction?.Invoke(result); return result; } catch (Exception ex) { exceptionAction?.Invoke(ex); return default(T); } finally { finallyAction?.Invoke(); } } } public class MyInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { try { // 先呼叫原始方法 invocation.Proceed(); // 如果返回值是泛型任務,使用 CallGenericMethod if (invocation.Method.ReturnType.IsGenericType && invocation.Method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) { var result = IInvocationProgram.CallGenericMethod(invocation, callBackAction: (obj) => Console.WriteLine($"回撥執行,結果為:{obj}"), exceptionAction: (ex) => Console.WriteLine($"異常捕獲:{ex.Message}"), finallyAction: () => Console.WriteLine("最終執行")); Console.WriteLine($"動態呼叫的結果: {result}"); } } catch (Exception ex) { Console.WriteLine($"攔截器捕獲到異常:{ex.Message}"); } } public static void Main() { // 建立代理生成器 var proxyGenerator = new ProxyGenerator(); // 建立 MyService 的代理物件,並注入攔截器 var myService = proxyGenerator.CreateInterfaceProxyWithTarget<IMyService>(new MyService(), new MyInterceptor()); // 呼叫方法,將觸發攔截器 var task = myService.DoSomethingAsync(); task.Wait(); // 等待非同步任務完成 } }