RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


How To Create a Custom Policy Injection Application Block Handler : Page 4

Using custom policy injection, you can configure and apply policies exactly the way you want—but doing it right requires a little effort.

Integrating the Handler with the Configuration Tools
To integrate a provider with the Enterprise Library configuration tools, the tools must contain classes that define the type of editing node(s) to create for that provider. Enterprise Library providers include common items such as database providers, cache backing stores, and Windows Event Log providers. However, the Matching Rules and Call Handlers used by the Policy Injection Application Block are also providers—they act as extension points for the block that allow developers to extend the behavior of the block to suit their own requirements.

Creating the Configuration Editor Node Class
The custom handler described in this article is quite simple, and requires only a single configuration editor node, and no child nodes unlike more complex providers such as those used in the Logging and Caching Application Blocks. The configuration editor node is defined in the NeverOnASundayCallHandlerNode class (see the file NeverOnASundayCallHandlerNode.cs in the App Blocks\Src\PolicyInjection\CallHandlers\Configuration\Design subfolder of the Enterprise Library source code). If you are editing the existing Enterprise Library project, you must ensure that you place the class in the correct namespace (Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.Configuration.Design), and add using statements for the other namespaces required. Open the sample project to see the complete file.

The following code shows the NeverOnASundayCallHandlerNode class, which inherits from the CallHandlerNode base class that implements most of the required functionality. The class contains two constructors. The first generates instances with the default handler name, as stored in the Resources file. The second constructor accepts an existing instance of the NeverOnASundayCallHandlerData configuration data class containing the handler name, and sets the value of the NotSaturdayEither property using the data in the existing instance:

   public class NeverOnASundayCallHandlerNode : CallHandlerNode
      Boolean notSaturday;
      public NeverOnASundayCallHandlerNode() 
         : this(new NeverOnASundayCallHandlerData(
      { }
      public NeverOnASundayCallHandlerNode(
         NeverOnASundayCallHandlerData callHandlerData)
         : base(callHandlerData)
         this.notSaturday = callHandlerData.NotSaturdayEither;
      [SRDescription("NotSaturdayDescription", typeof(Resources))]
      [SRCategory("CategoryGeneral", typeof(Resources))]
      public Boolean NotSaturdayEither
         get { return notSaturday; }
         set { notSaturday = value; }
      public override CallHandlerData CreateCallHandlerData()
         NeverOnASundayCallHandlerData callHandlerData = 
            new NeverOnASundayCallHandlerData(Name);
         callHandlerData.NotSaturdayEither = notSaturday;
         return callHandlerData;
The remaining code in the NeverOnASundayCallHandlerNode class is the accessor for the NotSaturdayEither property, which specifies the category name and description (taken from the Resources file) to display in the configuration tools for this property, and the required override of the CreateCallHandlerData method. The CallHandlerNode base class defines this as an abstract method, which handlers implement to return an instance of the appropriate concrete handler configuration data class.

In the example handler, the CreateCallHandlerData method creates a new NeverOnASundayCallHandlerData instance using the name exposed by the base class, sets its NotSaturdayEither property using the value in this configuration node, and returns it to the caller.

As you saw earlier in the handler class, using values from the Resources for the project makes it easier to localize the code, or change the text in the future as required. The Resources.resx file contains the name of the node and the description of the single property for use in the configuration tools. Table 2 shows all the entries added to the Resources.resx file in the Properties folder of the PropertyInjection.CallHandlers.Configuration.Design project. The last two values are used in the code you will see later that registers the node and commands for the handler with the configuration tools.

Table 2: Values added to the Resources.resx file in the PolicyInjection.CallHandlers.Configuration.Design project.
Name Value
NeverOnASundayCallHandlerNodeName Never On A Sunday Handler
NotSaturdayDescription True if handler will prevent invocation on a Saturday
NeverOnASundayCallHandlerCommandText Never On A Sunday Handler
AddNeverOnASundayCallHandlerCommandTextLong Add Never On A Sunday Handler

Registering the Configuration Node Class
The final steps for integrating the new handler with the configuration tools are to register the node and the commands that manipulate the node. These steps require you to edit the existing registration files within Enterprise Library.

As the configuration tools load and initialize, they call the Register method in two files within each application block. The first file, named PolicyInjectionNodeMapRegistrar.cs (in the App Blocks\Src\PolicyInjection\CallHandlers\Configuration\Design subfolder of the Enterprise Library source code), registers the configuration node class. The following code shows what you must add to the Register method override in this class:

   public override void Register()
      ... code to register other handler nodes is here ...
      // register the new custom handler node
You can see that this code uses the name of the node ("Never On A Sunday Handler") as stored in the Resources file. The AddMultipleNodeMap method takes as parameters this name, the type that implements the handler node, and the type that stores the configuration data for the handler.

The final step is to modify the Register method override in the file that registers commands. This file, PolicyInjectionCallHandlerCommandRegistrar.cs (in the App Blocks\Src\PolicyInjection\CallHandlers\Configuration\Design subfolder of the Enterprise Library source code), contains calls to methods of the CommandRegistrar base class. These methods add the default commands (such as New and Rename), commands to reorder the handlers, and commands to add the specific child nodes for each of the handlers.

For the custom NeverOnASunday handler, you must add calls to the AddDefaultCommands, AddMoveUpDownCommands, and AddMultipleChildNodeCommand methods. Each of these methods accepts the handler node class type. The AddMultipleChildNodeCommand method also requires the short and long text to display in the console tooltips and status bar (taken from the Resources file), and the type of the parent node for this node (the "Handlers" node, as shown near the beginning of this article in Figure 1):

   public override void Register()
      ... code to register commands for other handlers is here ...
      // register the commands required to be available for this handler
This completes integration of the new custom NeverOnASunday handler with the configuration tools. As Figure 1 showed, you can now add the handler to an application's configuration, and set the NotSaturdayEither property. If you open the resulting configuration file in a text editor, you will see the <add> element that adds the handler to the configuration:

       <add name="Policy">
           <add notSaturdayEither="true"
             Version=, Culture=neutral, PublicKeyToken=null"
             name="Never On A Sunday Handler" />

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date