Microsoft & .NET.NETUsing a SectionHandler for Painless BizTalk 2004 Configuration

Using a SectionHandler for Painless BizTalk 2004 Configuration

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.

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.

DataSet Overview

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.

Putting It All Together

In the sample code, all of the Custom SectionHandler functionality is captured in a class called DataSetSectionHandler. As stated earlier, to implement the IConfigurationSectionHandler interface, add the Create function as in the example below.

public object Create(
   object parent,
   object configContext ,
   System.Xml.XmlNode section)
{
   Load (section);

   return _myDataSet;
}

The Create function returns an object to the code calling the ConfigurationSettingsGetConfig function. Populating the DataSet is done in the Load function. The Load function appears below.

public void Load ( XmlNode section )
{
   XmlReader xmlRead;

   xmlRead = new XmlNodeReader(section);

   _myDataSet = new DataSet();

   _myDataSet.ReadXml(xmlRead,XmlReadMode.InferSchema);

}

The Readxml function populates the DataSet with XML data and metadata. For optimal performance, online help recommends setting the XmlReadMode to be reflective of the data you are loading. In your solution, you’re loading XML without an included Schema.

One consideration mentioned earlier was to include the capability to refresh changes to the config file in running code. One quirk of the configuration file information is, once the file is loaded, the information is cached. The following code is a workaround for the cache issue.

public void Refresh()
{
   _myDataSet.Dispose();

   _myDataSet = null;

   Load (FindNodeSectionInCurrentConfig());
}

Now, look at how to invoke the DataSetSectionHandler.

Using DataSetSectionHandler

DataSetSectionHandler controls access to the encapsulated DataSet object. Once the data is loaded, you use the GetSettingValue* functions to retrieve the data from the DataSet. Thus, you can skirt the array limitation of the BizTalk Expression icon.

Also, by controlling creation of the DataSet, a class inheriting from DataSetSectionHandler can choose to update the DataSet data before returning data back to the invoking code. So, for example, you can call the refresh function each time you invoke a property in a class inheriting from DataSetSectionHandler.

When deploying the DataSetSectionHandler on your BizTalk server, remember to copy the SectionHandler assembly to the C:Program FilesMicrosoft BizTalk Server 2004 directory.

Using the DataSet was not the only solution under consideration. DataSet seemed to fit all of the criteria.

Alternatives

Here is a summary of the alternatives, along with a short explanation of why the alternatives didn’t fit all solution criteria.

Two alternatives were evaluated, the XmlSerializer object and a Typed DataSet.

The XmlSerializer allows a developer to Serialize the contents of a class into XML data or Deserialize XML into an instantiated class. You can use XmlSerializer to call DeSerialize and, violà, a class is populated with the data from the section in the config file. There are two limitations with this approach:

  • You still need to create a separate class for each config section.
  • Automatically refreshing the data would have been difficult to implement.

The second option, a Typed DataSet, showed promise until you use the Typed DataSet in the BizTalk Expression Icon. Typed DataSet members are accessed through arrays. As stated earlier, you cannot access arrays in the BizTalk Expression. The array limitation may not exist in BizTalk 2006 (currently in beta).

Conclusion

Configuration is often the last consideration on a BizTalk project, but important to providing something extra to support administration. A SectionHandler is perfect for organizing all of your configuration information. With the help of a DataSet reading and refreshing, XML configuration of data can be easy.

Download the Code

You can download the code that accompanies this article here.

Sources

Application Configuration Files Explained: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet04222003.asp

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories