看到了li-new的新文章获得系统异常的详细信息后,想到了前几天玩过的DynamicProxy和AOP,如果把这两个结合起来,不就是一个自定义的异常记录系统了么?
嗯,说做就做.
在这里,我没有使用JGTM的使用RealProxy的方法,原因我已在Dynamic For .NET中说得很明白了,不是吗:)
我们先写一个接口
public interface ICalculator{
void Run();
}
再实现我们的类.
public class Calculator : ICalculator{
public void Run(){
Console.WriteLine("hell,this is the run");
}
}
好了..现在我们就得写记录异常信息的类了...
记录异常信息,那得有一个Exception或是它的子类.嗯,Good~,我们写一个接口(为什么要写个接口?直接写类不是方便的多吗?为什么要这么麻烦呢?)
public interface ILog{
object LogException(Exception ex);
void Write(object res);
}
实现这个接口:
public class Log : ILog
{
#region ILog Members
public object LogException(Exception ex)
{
// TODO: Add Log.Write implementation
//这个地方的代码取自于获得异常信息的详细信息
StackTrace trace = new StackTrace(ex,true);
StackFrame sf;
string res = "";
MemberInfo mi;
for(int i=0;i<trace.FrameCount;i++){
sf = trace.GetFrame(i);
mi = sf.GetMethod();
res = mi.DeclaringType.Namespace + ".";
//class名
res = res + mi.DeclaringType.Name + ".";
res = res + mi.Name;
//取得文件名(物理路径)、行号,列号
if(sf.GetFileName() != string.Empty){
res = res + sf.GetFileName() + ",Line" + sf.GetFileLineNumber() + ",Col" + sf.GetFileColumnNumber();
}
}
Write(res);
return res;
}
public void Write(object res){
Console.WriteLine(res);
}
#endregion
}
在这里我们可以看到,LogException(...)函数就是用来从异常中取得信息,Write(...)函数就是用来把得到的异常信息通过命令行显示出来 : )
而且,在这里我是直接在LogException中调用Write的..
好了,记录异常的类Log已经写完了.现在该写在LogFactory类了:P
同样的,我们的LogFactory从DynamicProxy.IProxyInvocationHandler继承(不要问我为什么,去看DynamicProxy的代码自会明白)
public class LogFactory : DynamicProxy.IProxyInvocationHandler
然后再构造函数
由于我们要使用Log这个类来记录异常信息,所以构架函数是这样子的:
private object target;
private ILog log;
public LogFactory(object obj){
target = obj;
}
public LogFactory(object obj,ILog log){
target = obj;
this.log = log;
}
再实现生成动态代理的函数:
public object Create(){
return ProxyFactory.GetInstance().Create(this,target.GetType());
}
这就是函数调用的地方了:
public object Invoke(object proxy, System.Reflection.MethodInfo method, object[] parameters){
// TODO: Add LogFactory.Invoke implementation
try{
object result = method.Invoke(target,parameters);
return result;
}
catch(Exception ex){
if(log != null){ //判断log类是否不为空,如果为空,即不用记录:P
log.LogException(ex);
}
return null;
}
}
该写的都写了~再就是测试用例了:P
//这里不需要记录异常
[Test] public void TestRun(){
ICalculator cal = (ICalculator)(new LogFactory(new Calculator()).Create());
cal.Run();
}
//这里记录异常的信息
[Test] public void TestLogRun(){
ICalculator cal = (ICalculator)(new LogFactory(new Calculator(),new Log()).Create());
cal.Run();
}
OK了.,,这样子我们就完成了一个简单的异常记录系统(姑且这样子说吧)...
呵呵...我们还可以进一步写我们的XMLLog类,把异常信息记录到一个XML文件中,或是再写一个EnvenLog类,把异常信息放进系统的事件中:P
源代码下载: exceptionLog