Wcf “ErrorLoggingBehavior”
- “Neonatale”: lo sviluppatore utilizza WCF limitandosi ai template di progetto offerti da Visual Studio e ai proxy prodotti da Visual Studio/svcutil.exe;
- “Curiosa”: se lo sviluppatore è passato attraverso Web Services e in particolare attraverso WSE comincia a farsi tante domande sul perchè Wcf (e in particolare la sua infrastruttura) sia così apparentemente (e non solo apparentemente) complesso(a)….
- uno degli aspetti positivi, “più” positivi, è la ab-norme (cit.) possibilità di customizzazione e la capillarità della customizzazione;
- uno degli aspetti negativi che resta, anche nella versione 4.0, il vero tallone d’achille è la gestione della configurazione: quello che manca fondamentalmente è un tool degno del suo nome che permetta di gestire le infinite possibbilità di configurazione e l’infinita complessità a cui la configurazione può tendere;
ErrorLoggingBehavior
Dopo un bel po’ di ricerche, si perchè scoprite molto rapidamente che la documentazione su Wcf è un’altro dei punti deboli del sistema, approdate ad una cosa che ricade sotto il cappello di “Behavior”, un behavior è, molto all’acqua di rose, qualcosa che potete iniettare in un punto (in base al tipo di behavior) della pipeline di Wcf al fine di customizzare il comportamento di Wcf stesso, un esempio è proprio la necessità di intercettare tutti gli errori:
Fonte: Radicalpublic class Log4NetErrorLoggingServiceBehavior : IServiceBehavior, IErrorHandler
{
static readonly ILog logger = LogManager.GetLogger( typeof( Log4NetErrorLoggingServiceBehavior ) );
public void Validate( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase ) { }
public void AddBindingParameters( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters ) { }
public void ApplyDispatchBehavior( ServiceDescription serviceDescription, ServiceHostBase serviceHostBase )
{
foreach( ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers )
{
var channelDispatcher = channelDispatcherBase as ChannelDispatcher;
if( channelDispatcher != null )
{
channelDispatcher.ErrorHandlers.Add( this );
}
}
}
public void ProvideFault( Exception error, MessageVersion version, ref Message fault )
{
}
public bool HandleError( Exception error )
{
logger.Fatal( error );
return false;
}
}
Direi veramente banale, dopo che avete scoperto come farlo… la domanda che resta però ancora in sospeso è: bello… ok… ma come faccio ad agganciarlo al mio servizio Wcf? Nulla di più “facile”
BehaviorExtensionElement
Che ci permette di fare questo:public class Log4NetErrorLoggingServiceSection : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new Log4NetErrorLoggingServiceBehavior();
}
public override Type BehaviorType
{
get { return typeof( Log4NetErrorLoggingServiceBehavior ); }
}
}
In questo modo possiamo agganciare e sganciare il nostro behavior on-the-fly senza toccare il codice del servizio e avere finalmente accesso ad informazioni importantissime per capire quali sono i problemi che stanno impedendo al nostro servizio di funzionare correttamente… questo è fondamentale in particolare quando usate Wcf da un client Silverlight e cominciate a scontrarvi con il simpatico “NotFound”…<system.serviceModel>
<services>
<service name="MyService">
<endpoint address="" behaviorConfiguration="myBehaviorConfiguration"
binding="basicHttpBinding" bindingConfiguration=""
contract="IMyService" />
service>
services>
<extensions>
<behaviorExtensions>
<add name="log4NetErrorLoggingServiceBehavior" type="Topics.Radical.ServiceModel.Behaviors.Log4NetErrorLoggingServiceSection, Radical.ServiceModel, Version=1.0.0.23094, Culture=neutral, PublicKeyToken=null" />
behaviorExtensions>
extensions>
<behaviors>
<endpointBehaviors>
<behavior name="myBehaviorConfiguration">
<inlineWsdlEndpointExtension />
behavior>
endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<log4NetErrorLoggingServiceBehavior />
behavior>
serviceBehaviors>
behaviors>
system.serviceModel>
Happy Wcf-ing
.m