C# 常见行为的nlog测井模式

C# 常见行为的nlog测井模式,c#,c#-4.0,design-patterns,nlog,C#,C# 4.0,Design Patterns,Nlog,我在我的操作服务类中这样使用loggin public class MyServiceImplementation : IServiceInterface { static Logger log = LogManager.GetCurrentClassLogger(); public bool A() { try { lo

我在我的操作服务类中这样使用loggin

   public class   MyServiceImplementation : IServiceInterface
    {
           static Logger log = LogManager.GetCurrentClassLogger();

           public bool A()
           {
              try
              {
                 log.Trace("Started");                 
                 // Do something A
                 log.Trace("Completed");
                 return true;
              }
              catch( Exception e )
              {
                  log.Error(e);               
              }
              return false;
           }


           public bool B()
           {
              try
              {
                 log.Trace("Started");                 
                 // Do something B
                 log.Trace("Completed");
                 return true;
              }
              catch( Exception e )
              {
                  log.Error(e);
              }
              return false;
           }
    }
作为日志的结果,我看到了相当多的记录

MyServiceImplementation:B   Started
MyServiceImplementation:B   Completed
MyServiceImplementation:A   Started
MyServiceImplementation:A   Completed
但从代码设计的角度看,由于逻辑的重复,它并不漂亮,我想以

   public class   MyServiceImplementation : IServiceInterface
    {
           static Logger log = LogManager.GetCurrentClassLogger();

           private bool CallMethod( Action m )
           {
              try
              {
                 log.Trace("Started");                 
                 m();
                 log.Trace("Completed");
                 return true;
              }
              catch( Exception e )
              {
                  log.Error(e);               
              }
              return false;

           }

           public bool A()
           {
              return CallMethod(()=> { //Do Something A  } )
           }

           public bool A()
           {
              return CallMethod(()=> { //Do Something B  } )
           }


    }
但在本例中,我在日志中丢失了stacktrace,关于A或B方法调用losted的信息,我在所有情况下都看到CallMethod

MyServiceImplementation:CallMethod   Started
MyServiceImplementation:CallMethod   Completed
MyServiceImplementation:CallMethod   Started
MyServiceImplementation:CallMethod   Completed
如何实现两个目标——漂亮的日志记录和漂亮的代码?

是你的朋友

i、 e

也可以使用PostSharp之类的库。AOP是横切关注点(如日志记录)的完美选择


或者您可以使用DI容器拦截,比如说,这是一种基本的有限AOP,不需要AOP编译器或二进制输出结果中的编译后更改。

谢谢您的回答,但在我的解决方案中,我并没有将方法名写入日志消息,它是由调用堆栈中的nlog自动计算的。在您的示例中,我只写Started,前缀A或B是在运行时计算的——在方法A和B中都是逻辑IID的复制。但我想写一个常见的包装器void Wrap动作A traceStarted;A.traceCompleted;}并在所有方法中使用它,比如void A{Wrapper=>..;},而不丢失callstack,nlogMy代码中的方法名只是loggin的decorator模式的一个示例。我认为,如果在我的代码中使用nlog和stacktrace,您应该得到类似LoggedServiceImpl:A的东西。使用decorator模式,您可以分离责任,这比将loggin和域逻辑放在同一个类中要好。在您的示例中,使用nlog stacktrace,我将获得LoggedServiceImpl:A启动,它是从stacktrace自动计算方法名。您不需要手动写入方法名称。在本例中,方法A和B完全相同——都包含相同的字符串log.TraceStarted和log.TraceCompleted,我想用公共方法编写这个行为。
interface Iservice{

bool A()
bool B()

}

class ServiceImpl : Iservice {

bool A(){//do something}

bool B(){//do something}

}

class LoggedServiceImpl : Iservice{

Iservice innerService:

public LoggedServiceImpl(Iservice innerServ){

innerService = innerServ;

}

public bool A(){

trace("A started");
bool res = innerService.A
trace("A ended");
return res
}

public bool B(){

trace("B started");
bool res = innerService.B
trace("B ended");
return res
}

}

Iservice myService = new ServiceImpl();
Iservice myLoggedService = new LoggedServiceImpl(Iservice);
Console.WriteLine(Iservice.A();)
Console.WriteLine(Iservice.B();)