*DataContext.Log –> log4net…
Questo, se avete un debugger attaccato, o siete in un’applicazione Console, scrive sulla Console (Output Window per il debugger) i messaggi di Log del DataContext, tra cui tutte le query T-Sql con i parametri etc etc…using( var dc = new MyDataContext() ) { dc.Log = Console.Out;
}
Adesso supponiamo che vogliate scrivere quel log su un vostro sistema di Log, sia esso log4net, come nel mio caso, o il motore di Tracing di .net, poco importa quale sia la destinazione; in tutti i casi l’inghippo è che da una parte avete un TextWriter mentre dall’altra avete un metodo da chiamare tipicamente passando un messaggio sottoforma di stringa.
Per log4net ho trovato questa soluzione abbastanza complessa, a mio modo di vedere, che per inciso non funziona… ;-) o meglio se usate log4net in maniera basilare si, ma se cominciate a fare cose un po’ strane allora ciccia, non da errori ma non scrive nulla. All’inizio ci ho ragionato sopra un po’ cercando di capire quale fosse il problema… poi “blink” :-)
ActionTextWriter, di una semplicità disarmante: altro non fa che intercettare le chiamate a “Write” del TextWriter e redirigerle sul delegato di tipo Actionpublic sealed class ActionTextWriter : TextWriter { readonly Action<String> logger; public ActionTextWriter( Action<String> logger ) { Ensure.That( logger ).Named( "logger" ).IsNotNull(); this.logger = logger; } public override void Write( string value ) { this.logger( value ); } public override void Write( char[] buffer, int index, int count ) { if( buffer == null || index < 0 || count < 0 || buffer.Length - index < count ) { //let base class to throw exception base.Write( buffer, index, count ); } this.logger( new String( buffer, index, count ) ); } Encoding _encoding; public override Encoding Encoding { get { if( this._encoding == null ) { this._encoding = new UnicodeEncoding( false, false ); } return this._encoding; } } }
Per usarlo quindi, nel mio caso con log4net, mi limito a fare:
Semplice, funzionale e senza seg*e mentali di sorta ;-)static readonly ILog logger = LogManager.GetLogger( typeof( MyRepository ) );using( var dc = new MyDataContext( this.connectionString ) ) { dc.Log = new ActionTextWriter( s => logger.Debug( s ) ); }
.m