大型系統需監控執行效能,問題出現時能快速鎖定耗時方法。動態代理可輕鬆攔截方法呼叫並記錄耗時。以下為 ESBasic.Emit.Aop.Interceptors.MethodTimeInterceptor 記錄片段:
2009-4-17 18:50:12: TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData 方法耗時: 390ms
2009-4-17 18:50:16: TY.Web.MemberInterface.IMemberBL.GetOne 方法耗時: 106ms
2009-4-17 18:50:23: TY.Web.MemberInterface.IMemberBL.GetOne 方法耗時: 105ms
2009-4-17 18:50:24: TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData 方法耗時: 386ms
2009-4-17 18:50:30: TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData 方法耗時: 387ms
2009-4-17 18:50:35: TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData 方法耗時: 377ms
2009-4-17 18:50:43: TY.Web.MemberInterface.IMemberBL.GetOne 方法耗時: 105ms
2009-4-17 18:51:14: TY.Web.MemberInterface.IGameBenefitBL.GetMemberBenefitData 方法耗時: 714ms
假設 BL 層透過 Remoting 發布服務,介面為 IBL。不直接發布實作類別 BLObject,而是發布經動態代理攔截的代理物件:
// 介面
public interface IBL { }
// 實作
public class BLObject : IBL { }
// 建立記錄器:只記錄超過 100ms 的呼叫,避免日誌過大
IMethodTimeLogger logger = new MethodTimeLogger(new FileAgileLogger("TimeLogger.txt"), 100);
IBL blObject = ...; // BLObject 實例
// 建立 AOP 動態代理,掛載 MethodTimeInterceptor
IBL blObjectProxy = DynamicProxyFactory.CreateAopProxy<IBL>(blObject, null, new MethodTimeInterceptor(logger));
blObjectProxy 同樣實作 IBL,所有呼叫轉發給 blObject 並記錄耗時。將代理發布為 Remoting 服務即可監控所有 BL 方法效能。
IMethodTimeLogger 為記錄器介面,可自行實作寫入檔案、資料庫等。MethodTimeLogger 第二個建構參數 100 為閾值(毫秒),僅記錄超過閾值的呼叫,防止日誌膨脹。相關類別位於 ESBasic.dll,動態代理基於 Emit 實現,有興趣可用 Reflector 研究原理。