Propriedade customizada log4net PatternLayoutConverter (com índice)

É possível criar um PatternLayoutConverter personalizado log4net que permita que um valor de "índice" seja configurado? Eu sei sobre a string de conversão "property" que permite escrever código como este:

ThreadContext.Properties["ID"] = yourID;

E especifique assim:

%property{ID} 

Que o valor deve ser incluído na saída.

E se os valores que eu quero registrar estiverem em algum outro "dicionário"? Suponho que eu poderia escrever alguma lógica para copiar esses valores do dicionário para um dos contextos log4net e, em seguida, apenas usar o%property símbolo. E se eu quiser que o log4net registre os valores diretamente do meu "dicionário" com base em um valor de índice especificado no arquivo de configuração?

Posso escrever meu próprio PatternLayoutConverter que me permita configurar algo como isto:

%myproperty{ID}

E, em seguida, puxe o valor "ID" correspondente do meu "dicionário"?

Para quem estiver interessado, é muito fácil fazer o mesmo com o NLog:

  [LayoutRenderer("MyGDC")]
  class GdcLayoutRenderer : LayoutRenderer
  {
    [RequiredParameter]
    [DefaultParameter]
    public string Item { get; set; }

    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
      string msg = GDC.Get(this.Item);
      builder.Append(msg);
    }

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
    {
      return 10;
    }
  }

E configurado assim:

Informe o NLog sobre quaisquer montagens com extensões:

  <extensions>
    <add assembly="NLog.Extensions"/>
  </extensions>

Use a propriedade "indexada" em um layout:

  <layout="${longdate} | ${MyGDC:item=name} | ${message}"/>

Neste exemplo, estou realmente usando o objeto GDC do NLog como meu "dicionário", mas estou demonstrando como consegui escrever meu próprio LayoutRenderer "indexável" (mais ou menos equivalente ao PatternLayoutConverter da log4net) para acessar um valor indexado por um valor em o arquivo de configuração.

[EDIT] Eu recebi a resposta que queria. Eu incluí o código para o meu exemplo PatternLayoutRenderer aqui. No meu teste, eu tenho um dicionário estático na minha classe de formulário principal, onde eu poderia armazenar "configurações do aplicativo". Eu criei um PatternLayoutConverter que pode aceitar uma chave como parâmetro para que o conversor possa procurar o valor correto no dicionário. Talvez eu consiga alcançar a mesma funcionalidade usando os objetos de contexto log4net (ou NLog), mas em nosso aplicativo podemos ter algumas configurações ou informações de sessão que o aplicativo manterá para outros fins e queremos poder adicioná-lo ao saída de log. Como ele já estará em uma estrutura de pesquisa, seria bom poder referenciar os dados diretamente, em vez de precisar copiá-los explicitamente para o log4net (ou contexto NLog).

Enfim, aqui está o código:

namespace Log4NetTest
{
  class KeyLookupPatternConverter : PatternLayoutConverter
  {
    protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
    {
      //Use the value in Option as a key into the "application settings" stored on the main form.
      string setting;
      if (Form1.AppSettings.TryGetValue(Option, out setting))
      {
        writer.Write(setting);
      }
    }
  }
}

Configuração de layout:

  //Log the "sessionid" and "userid" values from our "application settings" object
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%d [%t] %-5p [session = %KLPC{sessionid}] [user = %KLPC{userid}] %m%n"/>
    <converter>
      <name value="KLPC" />
      <type value="Log4NetTest.KeyLookupPatternConverter" />
    </converter>
  </layout>

questionAnswers(1)

yourAnswerToTheQuestion