這兩天寫ASP.NET 寫暈了,老想偷點懶。由於在後台的程式碼裡幾乎每個方法裡都要try..catch 這麼來一遍,感覺很煩瑣。又聯想到AOP, 但AOP 的做法相對比較複雜,做法也很多。例如用Dynamic Proxy, Attribute, 或者Emit 等。我突然聯想到了C# 2.0 的新特性匿名委託,覺得這個雖然醜一點。 。 。不過其實也可以比較輕量級的簡單模擬AOP 的效果:
// asp.net 裡面強製做一個頁面基底類別的要求是不過分的。 。 。
public partial class TestLogger: PageBase {
protected void Page_Load(object sender, EventArgs e) {
// 這個方法實作在頁面基底類別裡面,可以往裡面實作通用的例外處理,日誌邏輯等。
TryDo(
// 這個裡面做實際的事情
delegate() {
int a = 1;
int b = 0;
int c = a / b;
},
// 這是一個可選的異常處理,如果傳遞一個null 就會乾脆忽略異常
delegate() {
Response.Write("Sorry, 發生了一個錯誤。");
}
);
}
}
在頁面基底類別裡面的實作程式碼就很簡單了,也可以方便的統一管理。這裡我假定僅僅簡單的用log4net 來對異常做日誌記錄:
using System;
using System.Web.UI;
using log4net;
namespace SomeNamespace {
// 定義一個簡單的委託用於傳遞匿名委託
public delegate void MyAction();
// 定義頁面基類
public class PageBase : Page {
protected ILog logger;
// 頁面基類裡面集中處理所有異常處理邏輯
protected void TryDo(MyAction doHandler, MyAction exceptHandler) {
try {
// 幹點兒實際的事情
doHandler();
} catch (Exception ex) {
// 簡單的記錄異常
logger.Error(ex);
// 其他一些處理
// 。 。 。
// 呼叫自訂的異常處理,這裡沒有回傳Exception 的具體資訊。因為反正沒有必要對使用者顯示了。 。 。
if (exceptHandler != null)
exceptHandler();
}
}
protected override void OnInit(EventArgs e) {
// 初始化logger. 剛好這裡GetType() 可以取到子類別的實際型別
logger = LogManager.GetLogger(this.GetType());
base.OnInit(e);
}
}
}
好了,先寫到這裡。這只是我的一個簡單想法。目的在輕量級的實作異常或日誌的集中管理。當然這個和完整的AOP 概念是沒法比的,不過話說回來,好像目前在.NET 中還沒有很完美的AOP framework.
http://www.cnblogs.com/RChen/archive/2006/11/16/aspnet_exception_handling.html