2015-05-29 2 views
0

Я использую Логгина в моем классе операции обслуживания таким образомNlog шаблон протоколирования для общего поведения

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 }) 
      } 


    } 

, но в этом случае я потерял стопку в журнале и информации о методе или B звонит Losted, я вижу CallMethod во всех случаях

MyServiceImplementation:CallMethod Started 
MyServiceImplementation:CallMethod Completed 
MyServiceImplementation:CallMethod Started 
MyServiceImplementation:CallMethod Completed 

Как взять две цели - довольно лесозаготовки и довольно-код?

ответ

0

Decorator pattern - твой друг.

т.е.

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();) 

Или вы можете использовать AOP библиотеку как PostSharp. АОП идеально подходит для сквозных забот, таких как каротаж.

Или вы можете использовать перехваты контейнера DI, такие как Microsoft Unity, который является своего рода рудиментарным и ограниченным АОП, который не нуждается в компиляторе AOP или пост компилятора в результате двоичного вывода.

+0

Спасибо за ваш ответ, но в моем решении я не записываю имя метода в сообщение журнала, оно рассчитывается автоматически nlog из callstack. Я пишу только «Начал» и префикс A или B, вычисленный во время выполнения. В вашем примере - дублирование логики в обоих методах A и B. Но я хочу написать один общий обертка void Wrap (Action a) trace ("Started"); a(); След («Завершено»); } и использовать его во всех методах, таких как void A() { Wrapper (() => ....); } без потери вызова и имени метода в nlog – Json76

+0

Мой код - всего лишь пример декоратора для логгинга. Я думаю, что если вы используете nlog с stacktrace в моем коде, вы должны получить что-то вроде 'LoggedServiceImpl: A Started'. С шаблоном декоратора вы разделяете ответственность, которая лучше, чем логинг и логика домена в том же классе. – jlvaquero

+0

С nlog stacktrace в вашем примере я получу LoggedServiceImpl: A A Started, он автоматически оценивает имя метода из stacktrace. Вам не нужно писать имя метода вручную. И в этом случае метод A и B тождественно - все содержит одни и те же строки log.Trace («Started») и log.Trace («Completed»), и это поведение я хочу написать обычным способом. – Json76

Смежные вопросы