Twitter GitHub Facebook Instagram dirv.me

Daniel Irvine on building software

Applying multiple OpenRasta OperationInterceptors

10 June 2011

OpenRasta has the concept on an OperationInterceptor, a special class that runs before and after your handler method is called. It’s useful when you have a cross-cutting action that should apply across all your resources. A couple of typical examples are:

  1. Validation, when you need to validate the incoming resource object on a Put or Post
  2. Authorization, when you need to check that the authenticate user has rights to perform this action on the resource.
So you create a subtype of OperationInterceptor, and you hook it up in your IConfigurationSource like this:
ResourceSpace.Uses
    .CustomDependency<IOperationInterceptor, MyOperationInterceptor>
        (DependencyLifetime.Transient);

Unfortunately, OpenRasta only supports one OperationInterceptor. That makes the OpenRasta API much simpler: if OpenRasta supported multiple interceptors, it would need a mechanism for ordering each of the OperationInterceptor instances that you pass it.

Thanksfully it’s easy to get around because we can use create a CompositeOperationInterceptor that does our ordering for us. It’s dead simple and you’ll find the code below. This’ll work if you’ve got a ValidationInterceptor and an AuthorizationInterceptor (you’ll need to write these yourself, of course).

public class CompositeOperationInterceptor : OperationInterceptor
{
    readonly IEnumerable<OperationInterceptor> _interceptors;
    public CompositeOperationInterceptor(IDependencyResolver resolver)
    {
        _interceptors = new List<OperationInterceptor> {
            resolver.Resolve(typeof(ValidationInterceptor))
                                     as OperationInterceptor,
            resolver.Resolve(typeof(AuthorizationInterceptor))
                                    as OperationInterceptor
        };
    }
    public override bool BeforeExecute(IOperation operation)
    {
        return _interceptors.All(i => i.BeforeExecute(operation));
    }
     public override bool AfterExecute(IOperation operation,
                      IEnumerable<OutputMember> outputMembers)
    {
        return _interceptors.All(i => i.AfterExecute(operation, outputMembers));
    }

}

And in your IConfigurationSource you need to hook up your interceptors:

ResourceSpace.Uses.
    CustomDependency<ValidationInterceptor, ValidationInterceptor>
                                  (DependencyLifetime.Transient);
ResourceSpace.Uses.
    CustomDependency<AuthorizationInterceptor, AuthorizationInterceptor>
                                  (DependencyLifetime.Transient);
ResourceSpace.Uses
     .CustomDependency<IOperationInterceptor, CompositeOperationInterceptor>
                                  (DependencyLifetime.Transient);

Easy :)

Just on a final note: the exclusion of this feature in OpenRasta is a great example of API design. It keeps the design

About the author

Daniel Irvine is a software craftsman at 8th Light, based in London. These days he prefers to code in Clojure and Ruby, despite having been a C++ and C# developer for the majority of his career.

For a longer bio please see danielirvine.com. To contact Daniel, send a tweet to @d_ir or use the comments section below.

Twitter GitHub Facebook Instagram dirv.me