Passing Configuration Data into a Sitecore Pipeline Processor

I’ve created an example pipeline config and an example pipeline processor to explain how to pass configuration data to your custom processor. Let’s take a look at the patch config and example processor code:

using Sitecore.Collections;
using Sitecore.Diagnostics;
using Sitecore.Pipelines;
using Sitecore.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Xml;

namespace Hi.Sc.Pipelines
{
    public class ExampleProcessor
    {
        #region Fields

        private string _myArgument1 = string.Empty;
        private string _myArgument2 = string.Empty;
        private List<string> MyRawList = new List<string>();
        private List<string> MyStringList = new List<string>();

        #endregion

        #region Properties

        public MyObject MyObject { get; set; }
        public string MyProperty { get; set; }

        #endregion

        #region Constructor

        public ExampleProcessor()
        {

        }

        public ExampleProcessor(string myArgument1, string myArgument2)
        {
            _myArgument1 = myArgument1;
            _myArgument2 = myArgument2;
        }

        #endregion

        #region Methods

        public void Process(PipelineArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            Log.Warn("ExampleProcessor.Process", this);
            LogData();
        }

        public void AlternateProcessMethod(PipelineArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            Log.Warn("ExampleProcessor.AlternateProcessMethod", this);
            LogData();
        }

        public void AddString(string myStringArgument)
        {
            if (!string.IsNullOrEmpty(myStringArgument))
            { 
                this.MyStringList.Add(myStringArgument);
            }
        }

        public void AddMyRawString(XmlNode configNode)
        {
            Assert.ArgumentNotNull(configNode, "configNode");
            string attributeValue = XmlUtil.GetAttribute("value", configNode);
            MyRawList.Add(attributeValue);
        }

        private void LogData()
        {
            LogString("My Argument 1", _myArgument1);
            LogString("My Argument 2", _myArgument2);
            LogString("My Property", MyProperty);
            LogList("My String List", MyStringList);
            LogList("My Raw List", MyRawList);

            if (MyObject != null)
            {
                Log.Warn("MyObject.Name = " + MyObject.Name, this);
            }
        }

        private void LogList(string listName, IList list)
        {
            if (list != null)
            {
                foreach (string s in list)
                {
                    LogString(listName, s);
                }
            }
            else
            {
                LogString(listName);
            }
        }

        private void LogString(string name, string value = "")
        {
            if (!string.IsNullOrEmpty(value))
            {
                Log.Warn(string.Format("{0} = {1}", name, value), this);
            }
            else
            {
                Log.Warn(string.Format("{0} is empty."), this);
            }
        }

        #endregion
    }

    public class MyObject
    {
        public string Name { get; set; }
        public MyObject()
        {
            Name = "MyObject.Name";
        }
    }
}

Our patch config:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor type="Hi.Sc.Pipelines.ExampleProcessor, Hi.Sc" method="AlternateProcessMethod" runIfAborted="true">

          <param desc="My Argument 1">myArgument1_Value</param>
          <param>myArgument2_Value</param>

          <MyProperty desc="My Property">MyProperty_Value</MyProperty>

          <MyStringList hint="list:AddString">
            <SomeTag1>MyStringList_String1</SomeTag1>
            <SomeTag2>MyStringList_String2</SomeTag2>
            <SomeTag1>MyStringList_String3</SomeTag1>
          </MyStringList>

          <MyRawList hint="raw:AddMyRawString">
            <MyRawString value="MyRawList_MyRawString_Value1"/>
            <MyRawString value="MyRawList_MyRawString_Value2"/>
          </MyRawList>

          <MyObject ref="MyObjectNode/MyObject"/>

        </processor>
      </httpRequestBegin>
    </pipelines>

    <MyObjectNode>
      <MyObject type="Hi.Sc.Pipelines.MyObject, Hi.Sc" />
    </MyObjectNode>

  </sitecore>
</configuration>

The code passes values into our processor to give you an idea on how to pass custom data into a processor. This could help give ideas on processor reuse. I’ve added this to the httpRequestBegin pipeline so I can reload my page and check my log files to see the output. I’m also calling Log.Warn instead of Log.Info since I have my log level set to WARN. Here is the output from my log file:

8072 23:03:49 WARN  ExampleProcessor.AlternateProcessMethod
8072 23:03:49 WARN  My Argument 1 = myArgument1_Value
8072 23:03:49 WARN  My Argument 2 = myArgument2_Value
8072 23:03:49 WARN  My Property = MyProperty_Value
8072 23:03:49 WARN  My String List = MyStringList_String1
8072 23:03:49 WARN  My String List = MyStringList_String2
8072 23:03:49 WARN  My String List = MyStringList_String3
8072 23:03:49 WARN  My Raw List = MyRawList_MyRawString_Value1
8072 23:03:49 WARN  My Raw List = MyRawList_MyRawString_Value2
8072 23:03:49 WARN  MyObject.Name

Setting the ExampleProcessor:
Line 5 of our patch config above initializes our processor. The type attribute tells Sitecore the namespace.class, assembly to use. In this case it is Hi.Sc.Pipelines.ExampleProcessor in the Hi.Sc.dll. The method attribute allows us to override the default Process method. Since I have set the method attribute in my processor, my example processor will call the AlternateProcessMethod instead of the default Process method. You can see the result on line 1 of the log file output. If we remove this method attribute, it will call Process instead. The runIfAported attribute set to true will run our processor even if a previous processor in our pipeline calls args.AbortPipeline() to stop processing the subsequent processors in the pipeline.

Passing Arguments to Processor Constructor:
Lines 7 and 8 of our patch config allows us to pass two arguments to the constructor of ExampleProcessor on line 36. If we remove these lines, The constructor on line 31 of ExampleProcessor will be called instead. If we only remove line 7, we will get an error when instantiating our ExampleProcessor as we do not have a constructor defined for only one argument. Please note that the desc attribute of the param tag is optional. These parameters are passed in the order that they appear and if we switch the order of lines 7 and 8, then the values will be swapped around in our log file output.

Passing Properties:
Line 10 of our patch config allows us to pass a value to Property of our processor class. When the ExampleProcessor is initalized, it will match the tag on line 10 of our patch config to the property defined on line 25 of our ExampleProcessor. We just need to make sure the tag name matches the property name.

Passing Values to a List:
Line 12 of our patch config allows us to pass values to a list in our processor. The key here is the hint attribute. By setting the hint attribute to list:[name of method we define], we can fill a list we create in our class. By calling hint=”list:AddString”, this will call the method on line 60 of our ExampleProcessor. The tag names on lines 13 through 15 do not matter, but the value inside them is what will be added to our list on line 64.

Passing Values to a List using Raw:
Line 18 of our patch config allows us to reuse the hint attribute, but instead of using list:, we will use raw:[name of method we define]. When calling hint=”raw:AddMyRawString”, this will call the method on line 68 of our ExampleProcessor. Notice that when we use raw, a System.Xml.XmlNode will be passed in as opposed to the AddString method which has a string argument. When we have an XmlNode, we are able to use Sitecore.Xml.XmlUtil.GetAttribute to extract the value attribute as seen on line 71. We then add that to the MyRawList in this example.

Passing an Object using Ref:
Line 23 is an interesting one in our patch config. We can see that is setting a Property on line 24 of our ExampleProcessor class, since the tag has the same name as the property in our class. Here we can see that type is not a string, MyObject is defined on line 119 of our code. By using ref attribute, this points to another location in out patch config, here it is pointing to line 30 in our patch config where we have set the type attribute to know what type of object to return to our Property. Alternatively, we could just add a type attribute instead of a ref attribute and set the class and assembly to pass that to MyObject.

Advertisements

2 Responses to “Passing Configuration Data into a Sitecore Pipeline Processor”

  1. Aron Boyette Says:

    Thanks! Works like a charm. Also, I just wanted to add, the property configurations (as in “MyProperty” above) work with non-string properties. For example, if one has a bool property called MyBool, it can be set via true.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: