Log4Net: Как указать тип макета FileAppender из библиотеки?

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

Раньше мне удавалось использовать следующую конфигурацию приложения:

  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <threshold value="DEBUG />
    <file value="C:\Logs\MyConsoleApp.log"
          type="log4net.Util.PatternString" />
    <preserveLogFileNameExtension value="true" />
    <datePattern value="_yyyyMMdd" />
    <rollingStyle value="Date" />
    <appendToFile value="true" />
    <staticLogFileName value="false" />
    <layout type="MyConsoleApp.MyLogLayout">
      <conversionPattern value="%date{ISO8601}|%-5level|%message%newline" />
    </layout>
  </appender>

Затем я попытался переместить класс MyLogLayout в проект библиотеки «MyLibrary.MyLogLayout», импортировал его в MyConsoleApp и попытался обновить код моего приложения следующим образом:

  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <threshold value="DEBUG />
    <file value="C:\Logs\MyConsoleApp.log"
          type="log4net.Util.PatternString" />
    <preserveLogFileNameExtension value="true" />
    <datePattern value="_yyyyMMdd" />
    <rollingStyle value="Date" />
    <appendToFile value="true" />
    <staticLogFileName value="false" />
    <layout type="MyLibrary.MyLogLayout">
      <conversionPattern value="%date{ISO8601}|%-5level|%message%newline" />
    </layout>
  </appender>

При попытке запустить его я получаю такую ​​ошибку:

log4net:ERROR Failed to find type [MyLibrary.MyLogLayout]
System.TypeLoadException: Could not load type [MyLibrary.MyLogLayout]. Tried assembly [log4net, Version=1.2.15.0, Culture=neutral
, PublicKeyToken=669e0ddf0bb1aa2a] and all loaded assemblies
   at log4net.Util.SystemInfo.GetTypeFromString(Assembly relativeAssembly, Strin
g typeName, Boolean throwOnError, Boolean ignoreCase)
   at log4net.Util.SystemInfo.GetTypeFromString(String typeName, Boolean throwOn
Error, Boolean ignoreCase)
   at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.CreateObjectFromXml(
XmlElement element, Type defaultTargetType, Type typeConstraint)
log4net:ERROR Failed to create object to set param: layout

Я дважды проверил, что dll находится в той же папке и что ссылка работает должным образом. Что странно, так это то, что если я создаю класс MyConsoleApp.MyLogLayoutChild, который просто наследует все от MyLibrary.MyLogLayout и ссылаюсь на него, все работает, однако основной смысл помещения этого кода в библиотеку состоит в том, чтобы мне не приходилось создавать новый класс для каждого проекта, который я make, особенно тот, в котором нет никакой логики, кроме наследования всего от родительского класса.

Поддерживает ли log4net загрузку пользовательских типов из библиотеки dll или я просто что-то делаю не так?


person Paul Milla    schedule 16.12.2016    source источник
comment
Здесь компилятор думает, что проект вам не нужен, поскольку он не упоминается в коде. Вот почему наследование класса заставляет его работать, поскольку теперь есть явная ссылка на эту сборку.   -  person stuartd    schedule 16.12.2016
comment
Хм, похоже, вы правы, хотя я ссылаюсь на MyLibrary в других частях кода, я не делаю этого в моем файле Program.cs. Спасибо!   -  person Paul Milla    schedule 16.12.2016


Ответы (1)


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

<layout type="MyLibrary.MyLogLayout, MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
person Yuri Tceretian    schedule 16.12.2016
comment
Идеально! Это было самое простое решение, которое я искал. Одна из причин, по которой я хотел переместить его в библиотеку, заключалась в том, чтобы мне было легче копировать + вставлять мою конфигурацию log4net между проектами и не беспокоиться о том, чтобы не забыть реализовать код. Просто чтобы другие знали, что мне даже не нужно было включать Version, Culture или PublicKeyToken, достаточно было просто добавить пространство имен моей библиотеки. - person Paul Milla; 16.12.2016
comment
Да, но как только вы решите подписать свою библиотеку, вам нужно будет указать версию и PublicKey. Я не знал вашей ситуации и опубликовал более общее решение. - person Yuri Tceretian; 16.12.2016