his is the last entry in a series of articles on Microsoft's "patterns & practices" (p&p) Enterprise Library tools, and how you can use them in your ASP.NET applications. Enterprise Library provides a range of application blocks and features that make it easier to accomplish complex tasks such as accessing databases, caching and encrypting data, handling exceptions, and generating Event Log messages. It demonstrates and codifies best practices in design and implementation. Microsoft supplies Enterprise Library in source code form so you can learn from it and adapt it to suit your own specific requirements.
A previous article in this series
showed how easy it is to build a custom provider for an Enterprise Library application block. The article discussed building a custom backing store provider for the Caching Application Block, but the principles for creating providers that extend Enterprise Library are the same irrespective of the block that you need to extend.
However, custom providers are effectively second-class citizens within Enterprise Library because you can configure them only as an instance of the pre-defined custom provider type, and you must use a NameValueCollection as the Attributes property in the Configuration Console to pass values from the configuration into the provider at runtime. These restrictions are both unintuitive and error-prone, because users have no visual indication of the number of name/value pairs required, or the name and type of each one. In addition, the Configuration Console cannot enforce rules such as which values are required, which are optional, and what the valid data type is for each.
Configuration Console Design Support
The good news is that you can add classes and code to your provider that allows it to fully integrate with the Configuration Console, and become a first-class citizen within Enterprise Library. To achieve you must satisfy three basic conditions:
- Your provider must expose a constructor that takes as parameters the values the user will configure in the console.
- You must create one or more classes that store and expose the configuration data in the configuration file to your provider.
- You must create one or more classes that represent the nodes in the console tree view that the console uses during the configuration process.
|Figure 1. New Configuration Console Support: Here's the Configuration Console after adding support for the Custom File Cache Storage provider.|
Fulfilling these conditions requires some additional sub-stepsyou must also:
- Specify text strings for display in the console during the configuration process.
- Create a class that ObjectBuilder uses to generate your custom provider configuration.
- Modify the classes that add items to the menus in the configuration console and handle user interaction with these menus.
All this sounds like a daunting prospect and a complicated process, but in fact it is relatively simple as long as you take an ordered and careful approach to modifying the existing Enterprise Library classes. In this article, you'll see how to add Configuration Console design support to the custom file caching provider created in the previous article
. At the end of this process, it will integrate into the Configuration Console as shown in Figure 1
, where you can see that the Cache Manager menu now contains a "Custom File Cache Storage" option.
Adding Configuration Console support makes the process much easier and more intuitive (and discoverable) for users when selecting a custom provider. They no longer need to locate the containing assembly and specify the type because the Configuration Console now already knows the provider type. In addition, the Configuration Console can display a list of the properties required for the provider, and you can cause it to display specific controls or dialogs to make setting the properties easier and less error-prone. Figure 2 shows how users can set the CacheFilePath property of the custom provider using a Windows Save File dialog.
Adding Configuration Design Support
|Figure 2. Custom Dialog: The figure shows the Configuration Console using a Save File dialog to set the CacheFilePath property for the Custom File Cache Storage provider.|
The process for adding design support involves five main tasks:
- Determine the provider configuration requirements and decide which properties/attributes the configuration file will contain.
- Modify your custom provider class. Change the constructor parameters in your custom provider class, and make any other modifications required, so that it accepts separate parameters for each configuration attribute rather than receiving them all as a single NameValueCollection. Also change the configuration attribute on your class to specify the configuration data class type that your class will use within the Configuration Console.
- Create the configuration data and configuration node classes that describe the custom provider (including the attributes it requires), an assembler class that manages the build process for the class in ObjectBuilder, and classes that describe the properties for the provider and the way that the console exposes them for editing.
- Edit the resources file in the Design section to add entries for the text and commands displayed by the console for this provider node
- Execute node and command registration by editing the block-specific class that inherits from NodeMapRegister so that it registers the new provider node with the console, and the block-specific class that inherits from CommandRegister so that it registers the strings in the resources file as commands the console will display when configuring the new provider.
The rest of the sections in this article explore each of these five tasks in more detail. Note that a simple provider such as the custom cache backing store described in this article requires only a single configuration data class and a single configuration node class. You need more only if your provider needs to expose configurable child nodes in the console and therefore requires parent/child configuration settings (such as multiple configurable paths for a file caching provider).