Вопрос по log4net, configuration, unity-container – еще раз о log4net и конфиге Unity IOC

5

я наткнулся на некоторые из этих вопросов, лежащих на разных сайтах, и l4n officianados, похоже, ответили на вопрос об облегченной оболочке, которую log4net 'является' (Дон»ты понимаешь?) и тому подобные ошеломляющие факты.

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

Цель здесь не будетне перефразировать 144, а просто взять приличную ссылку, которая не Требуется захватить поток текучей среды, как бы.

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

Поэтому в ответ на одно нетерпеливое предложение я попытался создать нормальный экземпляр ILog каноническим способом:

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

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

Тем не менее, подпись для метода RegisterInstance хочетТип' не интерфейс.

Для тех, кто неПри поиске в объектной модели log4net, afficiananderos верны: l4n - это 'обертка» и ты можешьне понимаютип' для журнала штуковина.

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

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

container
  .RegisterInstance("Logger", Log, new ContainerControlledLifetimeManager())
.RegisterType
(
   "CtlrCtx", 
   new ContainerControlledLifetimeManager(), 
   new InjectionConstructor(new ResolvedParameter("MsgBldr")),
   new InjectionProperty("Log",new ResolvedParameter("Logger"))
);

Таким образом, хеш-коды для оригинального объекта Log и объекта Log, введенного в свойство моего маленького объекта Context, идентичны.

Тем не мение...

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

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

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

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

Спасибо

Stato

Зачем?' это определенно разумный вопрос. Ответ связан с одной точкой конфигурации. используя любой регистраторвезде' становится реальным бременем конфигурации, и обслуживание тяжелоЭйнт» часть, когда дело доходит до веселья. Stato Machino
Это'не является обычной практикой иметь регистраторы в качестве переменных экземпляра - ониобычно это статические (то есть классовые) переменные и в любом случае реализованы как синглтоны. Так что я неЯ думаю, что вы получаете какую-то выгоду, извлекая их из контейнера Unity - зачем вам это нужно? Vinay Sajip

Ваш Ответ

2   ответа
0
ILog logger = container.Resolve<ilog>();
logger.Log(Level.Debug, "Hello world");
</ilog>

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

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

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

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

private ILog Logger {get;set;} 

может быть просто введен, но это неКажется, что это вообще не работает, поскольку все через log4net все делается через интерфейсы, а конкретный регистратор прячется за кулисами с помощью Wizard of Oz.

5

Поможет ли использование InjectionFactory в Unity 2? (увидетьэтот вопрос). Тогда ваш конфигурационный код будет выглядеть примерно так:

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

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

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

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

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

Похожие вопросы