2 votes

Recasting Func to Specific Delegate

J'utilise la capacité de NLog à prendre des délégués au lieu de chaînes de caractères dans le cadre de l'appel au journal. Par exemple

log.Error(()=>"I am an error which was encountered at " + DateTime.Now)

Ce délégué n'est évalué que si la journalisation est activée. En théorie, cela permet une exécution plus rapide car le délégué n'est pas toujours évalué. Nifty.

Mes problèmes commencent lorsque j'emballe le logger NLog comme un bon consommateur de bibliothèque tierce. J'ai une interface comme

public interface ILog
{
 ...        
    void Error(string errorMessage, params string[] args);
    void Error(Func<string> messageGenerator);
    void Error(Exception excepetion, string errorMessage, params string[] args);
    void Error(Exception excepetion, Func<string> messageGenerator);
 ...
}

Alors une mise en œuvre comme

...

    public void Error(Func<string> messageGenerator)
    {
        //_log is an NLog logger
        _log.Error((LogMessageGenerator) messageGenerator);
    }
....

Mon problème est que dans mes journaux d'erreurs, les lambdas ne sont pas évaluées. J'ai joué un peu et je pense que le problème est que lorsque le Func est créé, il est créé comme un simple Func et ensuite, lorsqu'il est passé dans NLog, il est passé comme tel au lieu d'un LogMessageGenerator. La surcharge NLog qui accepte un objet est appelée. Je suppose donc que lorsqu'il compile les lambdas, le compilateur C# tente de typer statiquement leur retour en fonction du contexte.

 //log is raw nlog logger
 log.Error(()=> "I am a terrible error"); => LogMessageGenerator
 //log is my wrapper
 log.Error(()=> "I am an even more terrible error"); => Func<string>

Existe-t-il un moyen de construire mon implémentation ILog de sorte qu'elle appelle toujours la surcharge correcte de NLog sans prendre une dépendance explicite sur NLog dans mon interface en changeant la signature de la méthode pour prendre un LogMessageGenerator ? J'ai naïvement essayé de couler mon Func dans un LogMessageDelegate mais c'est un échec.

1voto

Jeff Points 13306

Essayez

public void Error(Func<string> messageGenerator)
{
    //_log is an NLog logger
    _log.Error(new LogMessageGenerator(messageGenerator));
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X