asp.net
這兩天寫 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.