callorchardcmsautofachandlers

Orchard CMS - How to specify the call order of content handlers?


Content handlers resolved by Autofac are returned in an unpredicatable order. I need some content handlers to be invoked in a specific order.

Example:

Feature A

Content handler A -> assigns / removes role X from a user content item

Feature B

Content handler B -> evaluates assigned roles and when role X is found it and takes further actions

As you see, in my case it makes no sense to call handler B before A as role X must be updated in A before B can even execute further actions based on the role X assignment.

Currently Autofac resolves the handlers in an ordering as follows

..., A, B, ...

but the handlers are stored in the handler list in the following order

... B, A, ...

Then Orchard invokes the handlers like

Handlers.Invoke(handler => ..., Logger);

which obviously calls the handlers in the order

... B, A, ...

Is there anything i can do to ensure a specific order?

Here is a discussion in google groups about a similar issue:

https://groups.google.com/forum/#!topic/autofac/HE66utFpvkg


Solution

  • You should never rely on the order of content handlers. If you need to run code in a specific order then you can define your own handler interface with a property for ordering your handlers. For example:

    public interface IMyHandler {
        int Priority { get; }
        void Invoke(ContentItem item);
    }
    

    You can register this interface with a custom Autofac module inside your Orchard module. Then inside a regular content handler you can inject IEnumerable<IMyHandler>. This will provide you with all registered handlers of IMyHandler type. Then you can order them by Priority and call them in a foreach loop.

    foreach (var handler in _myHandlers.OrderBy(x => x.Priority)) {
        handler.Invoke(item);
    }