title: When and where to set a custom IOperationInvoker?
body: <p>I'm trying to extend WCF so that I can have a RESTful web service, in which, for each operation, I perform a verification of the HTTP Authorization header, whose value I use to call a Login() method. </p>
  
  <p>After the login is done, I wish to invoke the operation's corresponding method checking if a  security exception is thrown, in which case I'll reply with a custom "access denied" message" using the appropriate HTTP Status Code.</p>
  
  <p>With this in mind, I thought implementing a IEndpointBehavior that applies an implementaion of IOperationInvoker to each operation (setting the DispatchOperation.Invoker property) would be a good idea.</p>
  
  <p>I decided to implement an IOperationInvoker using the Decorator design pattern. My implementation would need another IOperationInvoker in it's constructor to which the method invocations would be delegated.</p>
  
  <p>This is my IOperationInvokerImplementation:  </p>
  
  <pre><code>    public class BookSmarTkOperationInvoker : IOperationInvoker{
  
      private readonly IOperationInvoker invoker;
  
      public BookSmarTkOperationInvoker(IOperationInvoker decoratee)
      {
          this.invoker = decoratee;
      }
  
      public object[] AllocateInputs()
      {
          return this.invoker.AllocateInputs();
      }
  
      public object Invoke(object instance, object[] inputs, out object[] outputs)
      {
          BeforeOperation(); // Where there's code to perform the login using WebOperationContext.Current
          object o = null;
          try
          {
              o = this.invoker.Invoke(instance, inputs, out outputs);
          }
          catch (Exception exception)
          {
              outputs = null;
              return AfterFailedOperation(exception); // Return a custom access denied response
          }
  
          return o;
      }
  
      public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
      {
          throw new Exception("The operation invoker is not asynchronous.");
      }
  
      public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
      {
          throw new Exception("The operation invoker is not asynchronous.");
      }
  
      public bool IsSynchronous
      {
          get
          {
              return false;
          }
      }
  }
  </code></pre>
  
  <p>I decided to implement an IEndpointBehavior by extending the behavior I already needed (WebHttpBehavior) this way I only use one beavior. Here's the code I wrote:</p>
  
  <pre><code>public class BookSmarTkEndpointBehavior : WebHttpBehavior
  {
      public override void Validate(ServiceEndpoint endpoint)
      {
          base.Validate(endpoint);
      }
  
      public override void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
      {
          base.AddBindingParameters(endpoint, bindingParameters);
      }
  
      public override void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
      {
          base.ApplyDispatchBehavior(endpoint, endpointDispatcher);
  
          foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
          {
              IOperationInvoker defaultInvoker = operation.Invoker;
              IOperationInvoker decoratorInvoker = new BookSmarTkOperationInvoker(defaultInvoker);
              operation.Invoker = decoratorInvoker;
  
              Console.Write("Before: " + ((object)defaultInvoker ?? "null"));
              Console.WriteLine(" After: " + operation.Invoker);
          }
      }
  
      public override void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
      {
          base.ApplyClientBehavior(endpoint, clientRuntime);
          throw new Exception("The BookSmarTkEndointBehavior cannot be used in client endpoints.");
      }
  }
  </code></pre>
  
  <p><b>Now here's the problem:</b></p>
  
  <ol>
  <li>Only the constructor is being invoked in the IOperationInvoker, none of the other methods are.</li>
  <li>The decoratee IOperationInvoker (the one that's passed in the decorator's constructor) is <b>null</b>.</li>
  </ol>
  
  <p><b>I'm guessing that maybe some other code from some other behavior is setting another IOperationInvoker in the OperationDispatcher.Invoker setting afterwards. Thus, overriding mine.</b> This would clearly explain my situation.</p>
  
  <p><b>What is happening and what should I do?</b></p>
  
  <p>My service is self-hosted.</p>
  
  <p>In case you need to see it, here is the configuration I have in the app.config file under system.serviceModel.</p>
  
  <pre><code>&lt;services&gt;
    &lt;service name="BookSmarTk.Web.Service.BookSmarTkService"&gt;
      &lt;host&gt;
        &lt;baseAddresses&gt;
          &lt;add baseAddress="http://localhost:8080/service"/&gt;
        &lt;/baseAddresses&gt;
      &lt;/host&gt;
      &lt;endpoint  
        address=""
        behaviorConfiguration="BookSmaTkEndpointBehavior"
        binding="webHttpBinding" 
        bindingConfiguration="BookSmarTkBinding"
        contract="BookSmarTk.Web.Service.BookSmarTkService"&gt;
      &lt;/endpoint&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  
  &lt;behaviors&gt;
    &lt;serviceBehaviors&gt;
      &lt;behavior name ="BookSmartkServiceBehavior"&gt;
        &lt;serviceDebug httpHelpPageEnabled="true" httpHelpPageUrl="/help.htm" includeExceptionDetailInFaults="true" /&gt;
      &lt;/behavior&gt;
    &lt;/serviceBehaviors&gt;
    &lt;endpointBehaviors&gt;
      &lt;behavior name="BookSmaTkEndpointBehavior"&gt;
        &lt;!--&lt;webHttp/&gt;--&gt;
        &lt;bookSmarTkEndpointBehavior /&gt;
      &lt;/behavior&gt;
    &lt;/endpointBehaviors&gt;
  &lt;/behaviors&gt;
  
  &lt;bindings&gt;
    &lt;webHttpBinding&gt;
      &lt;binding name="BookSmarTkBinding"&gt;
      &lt;/binding&gt;
    &lt;/webHttpBinding&gt;
  &lt;/bindings&gt;
  
  &lt;extensions&gt;
    &lt;behaviorExtensions&gt;
      &lt;add name="bookSmarTkEndpointBehavior" type="BookSmarTk.Web.Service.BookSmarTkEndpointBehaviorElement, BookSmarTk.Web.Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/&gt;
    &lt;/behaviorExtensions&gt;
  &lt;/extensions&gt;
  </code></pre>
  
  <p>I you read this far I am deeply grateful towards you. Really, Thank You!</p>