2017-02-08 4 views
0

Предположим, у меня есть утилита (например, журнал), которая может использоваться каждым классом в моем приложении. Я хочу, чтобы регистратор мог сохранять информацию о типе клиента, который использует регистратор, то есть если StockProvider хочет зарегистрировать сообщение, регистратор должен добавить имя класса StockProvider вместе с сообщением журнала. И StockProvider имеет регистратор передается через конструктор какПередайте информацию о клиенте к зависимости

public StockProvider (ILogger logger) {} 

поэтому он может использовать регистратор в своих методах. Я знаю, что проще всего передавать информацию о типе каждый раз, когда используется регистратор, например logger.Log (GetType(), msg). Я хочу, чтобы регистратор имел информацию о типе клиента в своем состоянии вместо того, чтобы передавать информацию этого типа методам регистрации, чтобы вызовы Log приводили к приложению, добавляющему имя типа. Например. передавая его с конструктором как

class Logger : ILogger { 
    public Logger (Type clientType) { 
     this.type = clientType; 
    } 
    public void Log(string msg) 
    { Console.WriteLine(this.type.FullName + msg); } 
} 

будет работать, как и тогда внутри StockProvider я мог бы просто сказать

logger.Log (msg) 

Так что вопрос: я в состоянии зарегистрировать Logger в таком общем виде, что он получает clientType клиента, который запрашивает регистратор, является ли он StockProvider или любым другим типом клиента? Обратите внимание, что я использовал регистратор как пример некоторого класса, который может быть широко использован в коде. Она также может быть своего рода издатель событий, хотел бы знать, кто инициирует событие

ответ

2

Вы можете создать общий регистратор как:

public interface ILogger<T> where T: class 
    { 
     void Log(string message, LogLevel level); 
    } 

    public class Logger<T> : ILogger<T> 
     where T: class 
    { 
     public void Log(string message, LogLevel level) 
     { 
      WriteLog(typeof(T).Name + ": " + message, level); 
     } 
    } 

И теперь вы должны зарегистрировать общую реализацию ILogger в вашем DI контейнер, например, в UnityContainer вы можете это сделать:

IUnituContainer container = new UnityContainer()' 
    container.RegisterType(typeof(ILogger<>), typeof(Logger<>)); 

Следующая ваш провайдер должен выглядеть следующим образом:

public StockProvider (ILogger<StockProvider> logger) {} 
+0

Прохладный. На самом деле я думал о таком подходе, но задавался вопросом, могу ли я уйти без параметра типа. И в этом весь вопрос. В любом случае спасибо за предложение - аккуратное решение! – patryk

0

Использование Log4Net, Вы можете сделать что-то вроде этого:

public class Import 
{ 
    private static ILog Log 
    { 
     get 
     { 
      if (LogManager.GetCurrentLoggers().Length == 0) 
      { 
       // load logger config with XmlConfigurator 
       log4net.Config.XmlConfigurator.Configure(); 
      } 
      return LogManager.GetLogger(typeof(Import)); 
     } 
    } 

В моем случае импорта это имя моего класса, как это видно. Вам нужно изменить этот фрагмент кода на основе ваших потребностей.

+0

Честно говоря, я использовал запись как пример некоторой реализации, которая широко используется. Это может быть и какой-то код публикации событий, для которого потребуется информация о том, кто публикует событие. Вопрос заключается исключительно в регистрации и разрешении – patryk

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