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.