As a busy BizTalk 2004 developer, your product's configuration settings are often your last considerations as you complete development. Yet, thoughtful, organized, self-documenting configuration settings are one of the "little things" that keep you in good graces with a product's administrator.
If you're like most developers, you probably pour all of your miscellaneous settings into the AppSettings section of the BTSNTSvc.exe.config file. Although using AppSettings is an acceptable practice, there are better ways to organize your configuration settings. An alternative to a cluttered AppSettings section is a SectionHandler.
I'm going to explain how to build a reusable SectionHandler for your miscellaneous BizTalk 2004 settings.
What Is a SectionHandler?
A SectionHandler is a class contained in a class library; it implements the IConfigurationSectionHandler interface. To use a section handler, you must place entries in an application's config file to instruct the .NET Framework configuration functions to use your class. An example of SectionHandler configuration information appears below.
<?xml version="1.0" encoding="utf-8" ?> - <configuration> - <configSections> <section name="ClientSurvey" type="Crowe.ConfigHandler.DataSetSectionHandler, Crowe.ConfigHandler" /> </configSections> - <ClientSurvey> <Security WS_Login="WS_Login_0" WS_Pwd="WS_Pwd_1" /> <URLs SendEmailURL="SendEmailURL_0" ClientSurveyURL="ClientSurveyURL_1" WaitTimeToCallWS="10" BeginCheckHour="12" EndCheckHour="7" /> <SQL MainDBConnectString="MainDBConnectString_0" /> </ClientSurvey> </configuration>
As you can see, a SectionHandler allows you to separate configuration information in your config file. In fact, a SectionHandler is a requirement if you want to avoid configuration setting naming collisions.
You use a SectionHandler in conjunction with the GetConfig function in the System.Configuration.ConfigurationSettings class. When you call the GetConfig function, ConfigurationSettings reads the Config file information and passes the raw XML from the section in the Config file to the Create function in the SectionHandler class.
That was the short explanation. For more detailed information, refer to the sources posted at the end of the article.
Building a SectionHandler for BizTalk is different than building a SectionHandler for other .NET applications. Before delving into code, you'll review some BizTalk considerations.
First, the SectionHandler solution must work with the BizTalk 2004 Expression icon. There are limitations imposed on classes used in a BizTalk Expression. For example, arrays are not supported in the Expression icon. Whereas the Expression icon allows classes with arrays, unfortunately, you can't reference members of an array from the Expression icon.
Also, the solution must be capable of refreshing configuration settings on each use. BizTalk performs Long Running Transactions. An Instance of a BizTalk Orchestration may persist for weeks or even months. Over time, servers are moved or even taken down for upgrades. Therefore, it is important to have a solution which re-reads configuration settings each time it uses them or, at least, provides the option to reread settings.
A BizTalk SectionHandler solution must accommodate a deep hierarchy of XML Elements and Attributes in the Configuration file.
Finally, a solution should have significant reusability. Writing new code every time you need a new set of configuration information is not reusability. Moreover, as with all BizTalk variables, classes must be Serializable.
Implementing the IConfigurationSectionHandler interface is straightforward. The key to the solution is the storage and processing of the configuration information. Rather than using XmlDocument API functions to store and parse the XML data, a simpler solution is to find a class that performs the storage and parsing for you.
The ADO.NET DataSet is the perfect storage and processing platform for XML data.
The ADO.NET DataSet object is the storage and processing foundation for the BizTalk Custom SectionHandler solution. A complete discussion of a DataSet could cover multiple articles. I'm going to highlight the items most important for this solution.
Think of a DataSet object as a small relational database. Like a relational databases, a DataSet contains tables, columns, rows of data, and metadata describing everything. Each of the relational database constructs are implemented in separate classes. The figure below captures a subset of the classes composing a DataSet.
Data and metadata in a DataSet can be populated from multiple data sources, including SQL Server and XML documents. The SectionHandler data is in XML format; therefore, you rely heavily on the XML functionality.
Now, look at how all of these pieces come together.