2009-08-24 2 views
5

Я столкнулся с несколькими из этих вопросов, которые лежат вокруг разных сайтов, и ответы, кажется, были развернуты на 4-4 ноября по отношению к значению облегченной обертки, что log4net 'is' (не вы это понимаете?) и подобные моменты ошеломляющего факта.еще раз о log4net и конфигурации Unity IOC

Однако кажется, что то, что запрашивают пользователи (и это мой вопрос), заключается в том, как поместить модель log4net objet в последовательность registertype/registerinstance в свободном интерфейсе конфигурации.

Цель здесь не в том, чтобы повторно обернуть l4n, а просто получить приличную ссылку, которая не требует захвата свободного потока, как это было.

плохой ejemplow, я хочу получить ссылку на сконфигурированный экземпляр ILog из метода LogManger.GetLogger и перевести его в свободный поток достаточно рано, чтобы ввести его в свойства моих объектов вниз по потоку.

Таким образом, в ответ на один нетерпеливый предложение, я попытался создал нормальный экземпляр Илог в канонической форме:

log4net.Config.XmlConfigurator.Configure(); 
static readonly log4Net.Ilog Log = LogManager.GetLogger(thatlongassemblyreflectionstuff); 

Так что, казалось бы тривиальным (в подлинном смысле усилий), чтобы теперь добавить эту ссылку к контейнеру «Единство» и продолжим свою прекрасную жизнь.

Однако подпись для метода RegisterInstance требует, чтобы «Тип» не был интерфейсом.

Для тех, кто не выполнил поиск по объектной модели log4net, афтерианцы правильны: l4n является «оберткой», и вы не можете получить хот фактического «типа» для журнала.

Так что теперь я должен проверить. И вы знаете, что это значит, это может занять минутку, но, скорее всего, займет час или четыре (подобные отношения, такие как написания «час» и «четыре», никогда не совпадают в реальной жизни).

Однако следующие минус Опущенная часть о канонической установке, сделала работа:

container 
    .RegisterInstance("Logger", Log, new ContainerControlledLifetimeManager()) 
.RegisterType<IControllerContext, ControllerContext> 
(
    "CtlrCtx", 
    new ContainerControlledLifetimeManager(), 
    new InjectionConstructor(new ResolvedParameter<IMessageBuilder>("MsgBldr")), 
    new InjectionProperty("Log",new ResolvedParameter<ILog>("Logger")) 
); 

Так что hashcodes для первоначально объекта Log и объекта Log инъецированного в собственность моего marvy маленького объекта Context идентичны.

Однако ...

Процесс впрыска требует, чтобы я выставить свойство Log объекта контекста через интерфейс, то есть его больше не может быть статическим объектом. И является ли объект log4net ILog статичным, по-видимому, решающим фактором в отношении того, является ли он сериализуемым и может быть разделен между сборками, без того, что резкие предупреждения «runtime станут неустойчивыми» (которые действительно значимы только для поклонников Matrix).

Отклонено, хотя и не отложено, я использовал свойство Resharper nifty для свойства с помощью поля поддержки и установил, что поле поддержки является статическим, в то время как свойство Interface оставалось нестатическим. Ну, он построил, и тест прошел зеленый.

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

Так что, возможно, это поможет

Благодарности

Stato

+0

Это не нормальная практика, когда регистраторы являются переменными экземпляра - они обычно являются статическими (т.е. классными) переменными и в любом случае реализованы как одиночные. Поэтому я не думаю, что вы получаете какую-либо выгоду, выбирая их из контейнера Unity - зачем вам это нужно? –

+0

'почему?' безусловно, является разумным вопросом. Ответ имеет отношение к одной точке конфигурации. использование любого логгера «повсюду» становится реальной нагрузкой на конфигурацию, и обслуживание очень тяжело для части «aint», когда дело доходит до удовольствия. –

ответ

5

Would с использованием InjectionFactory в Unity 2 помощи? (см. this question). Тогда ваш код конфигурации будет выглядеть следующим образом:

IUnityContainer container = new UnityContainer(); 
container.RegisterType<ILog>(new InjectionFactory(factory => LogManager.GetLogger())); 

Затем извлечь регистратор с обычным вызовом Resolve():

ILog logger = container.Resolve<ILog>(); 
logger.Log(Level.Debug, "Hello world"); 

Вы также могли бы быть в состоянии настроить срок службы регистратора также быть ContainerControllerLifetimeManager, чтобы сделать его экземпляром singleton, но я еще не подтвердил это.

+0

его вид похож на log4net, но полезен для экземпляра объекта, который также создается для запуска. Благодарю. –

0
ILog logger = container.Resolve<ILog>(); 
logger.Log(Level.Debug, "Hello world"); 

действительно работает.

Однако, если у вас есть свойство для регистратора в классе и вы хотите ввести этот экземпляр регистратора, это не будет работать AFAICT. Я думаю, что я могу быть вне цели, но я пытаюсь повторно использовать экземпляр журнала в новом контексте. Это может быть просто невыполнимым, так что я, возможно, придется отказаться от инъекционного его и просто добавьте строку

ILog logger = container.Resolve<ILog>(); 

к каждому классу, который дает мне результат, который только кажется, незначительно отличается от инстанцировании его в каждом классе .. ..

Я надеялся, что

private ILog Logger {get;set;} 

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

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