hBifTs

山自高兮水自深!當塵霧消散,唯事實留傳.荣辱不惊, 看庭前花开花落; 去留随意, 望天上云展云舒.

导航

自己做一个ExceptionLOG

Posted on 2004-03-30 15:50  hbiftsaa  阅读(2919)  评论(7编辑  收藏  举报

看到了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