Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dynamic data access in web projects using reflection and custom web sections

0.00/5 (No votes)
7 Nov 2005 2  
This article demonstrates: i) Creating custom sections in a web.config file ii) Creating Custom section handlers iii) Dynamically loading a data access library using reflection.

Introduction

Consider that you are building an application that will fetch data from unknown data sources, there can be single or multiple data sources, there will be a separate component to connect to each of the data sources. Suppose you want to give a plug and play type of feature in which you will just configure a data access component in your web.config file and copy it on the web server and your application should start fetching data from new data sources as long as the component is present on the web server.

In this demo we will see how to deal with such a scenario using reflection and custom section handling.

This article demonstrates the following things:

  1. Creating custom sections in the web.config file.
  2. Creating custom section handlers.
  3. Dynamically loading a data access library using reflection.

Before we begin let us get familiar with a few keywords that will be used in this article.

What are custom sections in a web.config file?

Normally, if we want to store configurable information for applications, we store it in the web.config file in the <AppSettings> section. A custom section is a more structured way of storing custom configurable data in the web.config file. We define our own custom tags and create custom handlers to handle the data.

What is a custom section handler?

A custom section handler is An object, which is used to fetch and manipulate data from custom sections in an XML configuration file. It typically returns the data stored in custom sections in the form of collections of objects. With the help of custom section handlers, you get the Intellisense for your configuration settings.

Platform

This application is developed in Visual Studio 2003, using the .NET Framework 1.1.

Solution

To achieve the target as mentioned above, we will create a sample web application. The application will fetch data from any plug and play data source at run time. The fetched data will be populated on a data grid. For this we will follow these steps:

  1. Information related to the data access components will be stored in the custom sections of the web.config file.
  2. The application will read data from custom sections using custom section handlers.
  3. Reflection will be used to load the data access components at run time and the appropriate method will be called to populate data.

Process

Data access component

The demo application includes two sample data access components. One will connect to a SQL server (SQLConnect); another will connect to a local XML file (XMLConnect). Both the components will implement a common interface IDBConnect.

Custom Sections in web.config

Shown below is how we define a custom section in a web.config file:

<configSections>
 <sectionGroup name="DS">
   <section name="VariousDataSources" 
      type="CustomConfigHandler.DBSourceHandler, CustomConfigHandler "/>
 </sectionGroup>
</configSections>

Note: you must declare a custom section as the first child element under the configuration element of the web.config file.

Also notice that you have to give the name of custom section handler and mention the complete name of the class with namespace. This class will be activated when you call the Configuration.GetConfig() method.

After defining custom sections, you will actually store data in the following way:

<DS>
   <VariousDataSources TotalCount="2">
       <DataSources>
            <Clear/>
            <DataSource IsActive="true">
               <AssemblyName>DBConnector_SQL.dll</AssemblyName>
               <AssemblyTypeName> DBConnector_SQL.SQLConnect</AssemblyTypeName>
               <ConnectionStr>Provider=SQLOLEDB;Data Source=pc-p41400;
                     Initial Catalog= Northwind;UserId=sa;Password=;</ConnectionStr>
            </DataSource>
            <DataSource IsActive="true">
               <AssemblyName> DBConnector_XML.dll</AssemblyName>
               <AssemblyTypeName> DBConnector_XML.XMLConnect</AssemblyTypeName>
               <ConnectionStr>C:\RData.Xml</ConnectionStr>
            </DataSource>
         </DataSources>
    </VariousDataSources>
</DS>

Custom Section Handler

Custom section handlers must implement the IconfigurationSectionHandler interface. Shown below is the declaration of a custom section handler:

public class DBSourceHandler : IConfigurationSectionHandler

It must implement the following method:

public Object Create(object parent, object context, XmlNode node){}

The Create method loads the data from custom sections in a collection-based object. The object is returned when Configuration.GetConfig() is called.

Loading the object at runtime

The following code snippet loads the data access library at run time:

Assemblyassembly = Assembly.LoadFrom(completePath);

The parameter completePath is the path of the assembly to be loaded. The sample application assumes that the assembly to be loaded should be present in the application's bin folder.

Using the sample application

The DBConnector_SQL component retrieves data from the Northwind database. Thus if you want to use this component to retrieve data, you need to configure your connection string in the following node in the custom section:

<DataSource IsActive="true">
   <AssemblyName>DBConnector2.dll</AssemblyName>
   <AssemblyTypeName>DBConnector2.SQLConnect</AssemblyTypeName>
   <ConnectionStr>Provider=SQLOLEDB;Data Source=pc-p41400;
           Initial Catalog=Northwind;User Id=sa;Password=;</ConnectionStr>
</DataSource>

The DBConnector_XML component retrieves data from an XML file. The sample file is available for download along with the sample code. To configure XMLConnect, you will need to change the path where you have downloaded the XML file. In the case of DBConnector_XML, the ConnectionStr node stores the path for the XML file.

<DataSource IsActive="true">
   <AssemblyName>DBConnector1.dll</AssemblyName>
   <AssemblyTypeName>DBConnector1.XMLConnect</AssemblyTypeName>
   <ConnectionStr>C:\RData.Xml</ConnectionStr>
</DataSource>

If you wish to disable any of these components then just set the IsActive attribute to false.

If you wish to add your own data access component then you just need to append the DataSource node. Suppose your component's file name is �MyComponentName.dll" and type name is MyTypeName then you should append the custom section as shown below:

<DataSource IsActive="true">
   <AssemblyName>MyComponentName.dll</AssemblyName>
   <AssemblyTypeName>MyNameSpace.MyTypeName</AssemblyTypeName>
   <ConnectionStr>MyConnectionString</ConnectionStr>
</DataSource>

Note: The test application, which loads the data in the web grid, assumes that the schema of data returned by the query will be the same for all the components. Thus if you wish to append your own component, then it must return the columns EmployeeId, LastName, and FirstName.

Sample Web application

Shown below is the screenshot of the sample web application:

Dynamic Data Access

Errors encountered during development

Below are some of the errors that were faced during the development:

  • Could not load file or assembly 'file:///C:\WINNT\system32\DBConnector2.dll' or one of its dependencies

    This error comes when you try to load a component at runtime using the Assembly.Load method. I resolved this error by using Assembly.Load(path) by giving the full path of the assembly to be loaded.

  • The given assembly name or codebase was invalid (Exception from HRESULT: 0x80131047)

    This error occurred when my custom section handler was not written properly. When I rewrote the custom section Handler the error disappeared.

Summary

  • Custom sections are user defined sections in the web.config file.
  • Custom sections require custom section handlers.
  • You can design your application in such a way that you can provide a plug and play feature for your data access component.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here