I have moved my active blog over to tumblr. I've maintained this blog for reference but will be posting to http://www.robustsoftware.co.uk instead. I've pointed my Feedburner feed to tumblr so if you're subscribed already you should already have switched with me.

A better ActionResult: Open Rasta edition (part 2)

Sebastien Lambla, who created Open Rasta, mentioned that I could use an operation interceptor rather than using a pipeline contributor as in the first “A better ActionResult” post.

I must admit that I didn’t know about operation interceptors which is the main reason I didn’t use one in the first post. I took this as an opportunity to learn a bit more about Open Rasta and so looked into what operation interceptors are and how to create them.

Creating an operation interceptor is an unsurprisingly simple task. You can either implement the interface IOperationInterceptor or inherit from OperationInterceptor which implements IOperationInterceptor with virtual methods that have no effect on the operation.

The latter is the easiest thing to do so that’s what how we’re going to implement our interceptor.

The IOperationInterceptor has 3 methods: BeforeExecute, RewriteOperation and AfterExecute. We want to work with the result of the operation so we’ll override AfterExecute. The way the interceptor works once invoked is virtually identical to the pipeline contributor, bar a little refactoring, as you can see:

public class CommandOperationResultInterceptor : OperationInterceptor

{

    readonly IDependencyResolver resolver;

 

    public CommandOperationResultInterceptor(IDependencyResolver resolver)

    {

        this.resolver = resolver;

    }

 

    public override bool AfterExecute(IOperation operation,

                                      IEnumerable<OutputMember> outputMembers)

    {

        var outputMember = outputMembers.FirstOrDefault();

        if (outputMember == null) return true;

 

        var command = outputMember.Value as CommandOperationResult;

        if (command == null) return true;

 

        outputMember.Value = ProcessCommand(command);

 

        return true;

    }

 

    object ProcessCommand(CommandOperationResult command)

    {

        resolver.AddDependencyInstance(command.GetType(),

                        command, DependencyLifetime.PerRequest);

 

        var commandHandlerType = typeof(CommandOperationResultHandler<>)

            .MakeGenericType(command.GetType());

 

        var commandHandler = (ICommandOperationResultHandler)

            resolver.Resolve(commandHandlerType);

 

        return commandHandler.Execute();

    }

}

This is a direct replacement for the pipeline contributor. It uses the exact same commands and command handlers as the pipeline contributor so the only other difference is that we have to register the operation interceptor rather than the pipeline contributor:

ResourceSpace.Uses.CustomDependency<IOperationInterceptor,

    CommandOperationResultInterceptor>(DependencyLifetime.Transient);

That’s all there is to it. Really simple given we had the code for the pipeline contributor already.

The only difference between the pipeline contributor and the operation interceptor is that rather than dealing with a single operation result there could be multiple output members. From what I can gather there is only ever one output member which is the assumption I’ve embedded in the interceptor but I may be mistaken.

Reflecting on the two approaches, I don’t think there’s much to chose between the two. I prefer the original method of using a pipeline contributor. It is more visible via the debug output of the pipeline and it is easier to retrieve the operation result at that point. However, knowing that operation interceptors exist and how to use them is beneficial. Another weapon in my Open Rasta armoury.