11

Sitecore ships with a bunch of disablers, like the SecurityDisabler and the EventsDisabler, but what if I want to write my own?

I have a bunch of item:saved event handlers that run but when I add a new item from a particular snippet of code I want to disable one of my item:saved event handlers' logic. If possible, I would like to have a solution that I could use for the same purpose in a custom pipeline processor too. How would I go about this?

13

Sitecore's built in disablers, like the SecurityDisabler and the EventsDisabler classes, all inherit the Sitecore-provided Switcher class. This class is an IDisposable that can be used to create disablers for use in both pipeline processors and event handlers, without issue.

The Switcher class is easy enough to implement, but I have written a more readable abstract class to serve as a base for disablers that you may find useful:

    public abstract class Disabler<TSwitchType> : Switcher<DisablerState, TSwitchType>
    {
        public Disabler() : base(DisablerState.Enabled)
        {
        }

        public static bool IsActive => CurrentValue == DisablerState.Enabled;
    }

    public enum DisablerState
    {
        Disabled,
        Enabled
    }

Note that the Switcher class is used for more than just Sitecore's disablers. It is also used for Sitecore's various ____Switcher classes, like the SiteContextSwitcher, the LanguageSwitcher, and more. The class works by reading from and moving objects in the stack, and arguably one of the most under-utilized features of the Sitecore API.


Example 1: Pipeline Processor Disabler

I first created the following disabler:

public sealed class SaveItemLogicDisabler : Disabler<SaveItemLogicDisabler>
{
}

I then created my <saveItem> pipeline processor and added a check to see if the disabler was active. If so, I skipped executing that processor. Note that I made the intentional implementation decision to not abort the pipeline, here, as there are other processors that I may still want to run.

    public override void Process([NotNull] SaveItemArgs args)
    {
        // this is managed in configuration (runIfAborted=true would have to be set to override the value)
        if (args.Aborted)
        {
            return;
        }

        Assert.IsNotNull(args.Item, "Item is null");
        Assert.IsNotNull(args.FallbackProvider, "FallbackProvider is null");

        args.ProcessorItem = args.Item;
        args.Result = args.FallbackProvider.SaveItem(args.Item);

        // check disabler and decide whether or not to continue execution
        if (SaveItemLogicDisabler.IsActive)
        {
            return;
        }

        // additional processor logic here...
    }


Example 2: Event Handler Disabler

Let's say that I want to use the same disabler for my item:saved events.

I can actually do the exact same check inside of my event handler:

    private void OnItemSaved([NotNull] object sender, [NotNull] EventArgs args)
    {
        Assert.ArgumentNotNull(sender, nameof(sender));
        Assert.ArgumentNotNull(args, nameof(args));

        if (string.IsNullOrWhiteSpace(this.RuleFolderId))
        {
            return;
        }

        // check disabler and decide whether or not to continue execution
        if (SaveItemLogicDisabler.IsActive)
        {
            return;
        }

        // additional handler logic here...
    }
  • If you can, can you provide an example of implementing a custom disabled to satisfy the use case you provided in the question? – Pete Navarra Oct 5 '16 at 1:38
  • Sure thing, @PeteNavarra. Give me a moment or two to update. – Zachary Kniebel Oct 5 '16 at 1:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.