This project is read-only.

How can I inject an object into an WCF IErrorHandler implementation with SimpleInjector

Apr 17, 2013 at 10:22 AM
My question is similar to below web post:
   http://stackoverflow.com/questions/1602810/how-can-i-inject-an-object-into-an-wcf-ierrorhandler-implementation-with-castle
Only difference is that I want to achieve it using SimpleInjector.

Please help.

Regards,
Prashant
Coordinator
Apr 17, 2013 at 2:04 PM
I'm not sure what it is you want to achieve. Can you be more specific?
Apr 18, 2013 at 6:08 AM
Following are the details:

I am using SimpleInjector to host the WCF service as below:
              System.ServiceModel.ServiceHost host = new SimpleInjectorServiceHost(simpleInjectorContainer, typeof(TImplementation), new Uri[0]);
              var behaviour = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
              behaviour.InstanceContextMode = InstanceContextMode.PerSession;
              behaviour.ConcurrencyMode = ConcurrencyMode.Multiple;
              behaviour.ReleaseServiceInstanceOnTransactionComplete = false;
              host.open(); 
I want to perform the global exception handling in this WCF service. Hence I have implemented ErrorHandlerWCF derived from IErrorHandler so that I can log the exception message using logger utility. The code is as below:
public class ErrorHandlerWCF : IErrorHandler, IServiceBehavior
{
    public ILogger Logger {get; set;}
    public bool HandleError(Exception error)
    {
        Logger.LogException(error);
        return true;
    }
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        // Shield the unknown exception           
    }
}
public class ErrorHandlerElement : BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new ErrorHandlerWCF();
    }
    public override Type BehaviorType
    {
        get
        {
            return typeof(ErrorHandlerWCF);
        }
    }
}
The App.config file is configured for the extension behavior for ErrorHandler so that it is bind to the WCF service for error handling
<extensions>
  <behaviorExtensions>
    <add name="errorHandler"
        type="ErrorHandlerElement, Public.Services" />
  </behaviorExtensions>
</extensions>
My requirement is that I want to inject the Logger object using SimpleInjector so that the Logger property is set to valid object in the ErrorHandlerWCF class.
How can I achieve this using SimpleInjector?

Thanks in advance.
Coordinator
Apr 18, 2013 at 2:34 PM
I must admit I'm not that experienced with WCF, but can't do do something like this:
foreach (var dispatcher in host.ChannelDispatchers.Cast<ChannelDispatcher>())
{
    dispatcher.ErrorHandlers.Add(simpleInjectorContainer.GetInstance<ErrorHandlerWCF>());
}
This way you resolve the ErrorHandlerWCF directly from the container and the ErrorHandlerWCF can have a constructor that takes in an ILogger dependency.
Apr 21, 2013 at 7:40 PM
Thanks for your reply.
I have tried the above code, the ErrorHanlderWCF is attached to each host.ChannelDispatcher at runtime. But when the exception is raised, the method ErrorHandlerWCF.HanldeError() is not invoked by the WCF framework.
Now I am thinking of modifying the ErrorHandlerElement class to instantiate the Logger object and pass it to ErrorHandlerWCF class.
 public class ErrorHandlerElement : BehaviorExtensionElement
 {
    protected override object CreateBehavior()
   {
       Logger logger = new Logger();
       return new ErrorHandlerWCF (logger);
  }
  public override Type BehaviorType
  {
     get
      {
         return typeof(ErrorHandlerWCF);
      }
  }
}
But then in this way I am not able to consume SimpleInjector as IoC container.
If I happen to get any solution using SimpleInjector for this, will definitely post it here.
Thanks.
Coordinator
Apr 21, 2013 at 9:32 PM
You might want to take a look at this article about writing highly maintainable WCF services. When you apply the patterns described in that article to your WCF service (and the rest of your application), adding such logging cross-cutting concern to your application would be very easy, without complex interaction with WCF (or any other framework technology such as MVC or Web API). That logger can simply be added by writing a decorator (few lines of code) and registering it in Simple Injector with just a single line.

Although that article will definitely not give an answer to your question, it might be possible that you can remove the need for that question to be answered completely. However, do note that it might be difficult to apply those ideas to your current code base.
Marked as answer by dot_NET_Junkie on 11/5/2013 at 7:39 AM