Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes, it is possible to encapsulate this kind of logging, using the <a href="http://msdn.microsoft.com/en-us/magazine/cc163302.aspx" rel="nofollow noreferrer">extensibility points built into WCF</a>. There are actually multiple possible approaches. The one I'm describing here adds an <code>IServiceBehavior</code>, which uses a custom <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ioperationinvoker.aspx" rel="nofollow noreferrer"><code>IOperationInvoker</code></a>, and does not require any web.config modifications.</p> <p>There are three parts to this.</p> <ol> <li>Create an implementation of <code>IOperationInvoker</code>, which wraps the method invocation in the required logging and error-handling.</li> <li>Create an implementation of <code>IOperationBehavior</code> that applies the invoker from step 1.</li> <li>Create an <code>IServiceBehavior</code>, which inherits from <code>Attribute</code>, and applies the behavior from step 2.</li> </ol> <h3>Step 1 - IOperationInvoker</h3> <p>The crux of <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ioperationinvoker.aspx" rel="nofollow noreferrer">IOperationInvoker</a> is the <code>Invoke</code> method. My class wraps the base invoker in a try-catch block:</p> <pre><code>public class LoggingOperationInvoker : IOperationInvoker { IOperationInvoker _baseInvoker; string _operationName; public LoggingOperationInvoker(IOperationInvoker baseInvoker, DispatchOperation operation) { _baseInvoker = baseInvoker; _operationName = operation.Name; } // (TODO stub implementations) public object Invoke(object instance, object[] inputs, out object[] outputs) { MyInfrastructure.LogStart(_operationName, inputs); try { return _baseInvoker.Invoke(instance, inputs, out outputs); } catch (Exception ex) { MyInfrastructure.LogError(_operationName, inputs, ex); return null; } MyInfrastructure.LogEnd("Add", parameters); } } </code></pre> <h3>Step 2 - IOperationBehavior</h3> <p>The implementation of <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.ioperationbehavior.aspx" rel="nofollow noreferrer">IOperationBehavior</a> simply applies the custom dispatcher to the operation.</p> <pre><code>public class LoggingOperationBehavior : IOperationBehavior { public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.Invoker = new LoggingOperationInvoker(dispatchOperation.Invoker, dispatchOperation); } // (TODO stub implementations) } </code></pre> <h3>Step 3 - IServiceBehavior</h3> <p>This implementation of <code>IServiceBehavior</code> applies the operation behavior to the service; it should inherit from <code>Attribute</code> so that it can be applied as an attribute to the WCF service class. The implementation for this is standard.</p> <pre><code>public class ServiceLoggingBehavior : Attribute, IServiceBehavior { public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints) { foreach (OperationDescription operation in endpoint.Contract.Operations) { IOperationBehavior behavior = new LoggingOperationBehavior(); operation.Behaviors.Add(behavior); } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload