After the birth of .NET 2.0, the provider model became common in .NET development. Most built-in features that deal with data support providers. Many third party applications, components and libraries are using data providers, too. In my opinion talking about data providers in .NET is unnecessary because almost all the readers of this article know the role of data providers in .NET development. After the .NET Framework 2.0 was released, data providers became a very common part of .NET development. Not only were there many common built-in data providers in .NET, but community members and companies created third party components for other data storage systems like Oracle or MySQL.
Nowadays you can't find anything in .NET that doesn't have appropriate data providers for all common data storage systems. Usually these data providers are free and open source so you can adapt them for your own needs.
However, one thing that isn't documented very well is how to write your data provider model for .NET applications. I looked for such a resource but didn't obtain any good results, so I decided to write it myself.
In this article you will learn how to write your own data provider in order to bring this common feature to your .NET components or applications.
There are some benefits in using the data provider model in a component or application. You can probably guess, but let me outline them here:
- You abstract your data manipulation portion of the code and isolate it from other. In this way, code becomes easier to write.
- It lets you easily switch between different data storage systems. You can use SQL Server or Oracle or XML just by implementing the appropriate data provider.
- You can use multiple data storage systems in parallel for different parts of your application or your components. In other words you can, for example, use SQL Server to store data about products and use XML to store details about orders.
But how can a data provider be written in .NET? To demonstrate the concepts in this article I will use the C# language, but Visual Basic can be used as well, without any differences in the structure. Only a code translation is required.
In a nutshell, the process of implementing the provider model consists of creating four main classes:
- Main data provider class.
- Data provider collection class.
- Data provider configuration class.
- Data provider manager class.
After writing these classes you usually need to implement at least a default data provider for your application or component, as well as a SQL Server or XML data provider. This lets your users be able to use your data provider without implementing a custom one. It also acts as a good implementation example to everyone who wants to write a new provider.
In the next section I'll discuss the implementation of each of the above mentioned classes with the help of a simple example. I will also implement a default SQL provider for this example.
Main Data Provider Class
The main data provider class is where you define the abstract representation of all the data manipulation methods that you need in your provider. Here you write a public abstract class that must be derived from the
System.Configuration.Provider.ProviderBase base class and has some public abstract methods that must be implemented by different data providers.
As a result, you always need to have a reference to
System.Configuration in your provider project.
Let's start by taking a look at Listing 1, which shows the code for the main data provider class.
Listing 1: Code for the main data provider class
As you see, the main provider class is an abstract class derived from
ProviderBase. It defines two public abstract methods to add a text value for a given ID or get a text for a specified ID. These two methods must be implemented in different data provider classes.
You should understand that this class is the place where you write the abstract definition of your provider methods.
Data Provider Collection
The data provider collection class is the portion of your implementation that takes care of provider configuration. Here you implement the behavior of your configuration elements for a list of providers.
To implement the data provider collection class you need to derive it from the
System.Configuration.ProviderCollection base class.
ProviderCollection is a class that exposes some properties and methods to work with the list of various data providers declared in your configuration file. This class is simply a collection class that implements the
IEnumerable base interfaces, so there isn't any major point to mention about it.
The key point here is overriding the default behavior of the
ProviderCollection class in order to return an instance of your main data provider class for a specified index.
Listing 2 shows the code for the
DataProviderCollection class, where I've implemented my data provider collection.
Listing 2: Data provider collection class
Usually, it is enough to start from a skeleton implementation like the one shown above and then use it for your concrete providers by replacing the names of the parameters and types.
Data Provider Configuration
The next step in developing a provider is writing a data provider configuration class. It contains the logic to manage the configuration of your provider and to get user's parameters and pass them to your provider.
Data providers work based on the configuration files of your applications. For desktop applications, this is the App.config file and, for web applications, it is the Web.config file. Please note that there is no difference in the implementation with respect to the structure of these files.
To implement this class you need to derive it from the
System.Configuration.ConfigSection base class and add some code for your own data provider requirements.
In your configuration class, you need to define a property of type
System.Configuraiton.ProviderSettingsCollection for the collection of provider settings. The property needs to return an instance of this type by getting it from the base class.
In addition, you can also add as many properties as you like, based on the different parameters that you need to extract from the configuration sections.
All these properties must be decorated with the
ConfigurationProperty attribute. This attribute gets a string name as a parameter and has an optional
DefaultValue property for specifying a default value.
Listing 3 updates the sample provider with a data provider configuration class.
Listing 3: The data provider configuration class
In this code I have defined two properties. The first property is called Providers and it's of type
ProviderSettingsCollection. It represents the
/> element in the application's configuration file. The value is retrieved by the base
The second property, Default, gets or sets the default provider name as a string. By default, this value is set to
Data Provider Manager
The last step in developing the data provider is creating the data provider manager class. To implement this class you don't need to inherit from a base class or implement an interface. Actually, you just need to write code based on your requirements.
The main purpose of the data provider manager is to initialize a concrete provider and load user configuration settings in memory.
During initialization, you need to retrieve the configuration section for your data provider and check its correctness. Then, you create an instance of the concrete provider in memory.
In order to work, your data provider manager must have a static public constructor that calls the
Listing 4 shows the code for my
Listing 4: The data provider manager class
In the above code snippet, I’ve declared two static fields that hold the current provider (Provider) and a collection of all defined providers in the configuration file (Providers). I’m going to set appropriate values for these two fields in the initialization phase.
In the static public constructor I've called the
method, which simply gets an instance of the
class by calling the
method with the configuration element name that I've chosen for my provider (in this case, it is
The next step was to set the
Providers field to the appropriate value by calling the
ProvidersHelper.InstantiateProviders method, which is a very good helper method provided by the .NET Framework. Finally, I set my providers to be read-only and then I set the default provider.
Default SQL Data Provider
At this point we're done with the implementation of the data provider model. It's very common to have a default data provider in your model to let users use it for their needs. This provider is often implemented for the most appropriate storage system.
Here I'm going to implement a SQL Server data provider for my sample provider model, to show you how easy the implementation can be. This is a result of the abstraction that we achieve by leveraging the provider model.
The code in Listing 5 shows a
SqlDataProvider class that implements the SQL data provider.
Listing 5: The SQLDataProvider class
Note that you need to inherit from your main data provider class and implement this abstract base class for your data provider. In addition override methods and write your own code, you usually need to override the Initialize method to get the name of the provider model along with a NameValueCollection instance with all the attributes in your provider configuration section. Using this NameValueCollection instance, you can retrieve information (like a connection string) from the configuration file.
Okay, the provider model and a sample SQL data provider for this model are ready. Now we can configure our applications to use the provider model.
To configure the application for using the provider model first we need to define our provider configuration section in
/> element, which is the direct child element of
<configuration />. Here we can add a
/> element with the name of the provider model configuration section element and the type of our data provider configuration class. Based on your needs, you can also embed the
/> element within a
Listing 6 shows the configuration for my sample provider model in an ASP.NET 3.5 web application configuration file. Please pay more attention to the last
/> element in bold.
Listing 6: Configuration of the sample provider
The next and last step is to add the main configuration section for the provider model within the
Listing 7 shows how I added this section to my configuration file.
Listing 7: Main configuration section
Now we're ready to test the provider model. I created an ASP.NET 3.5 web application project that has a simple page which gets input from the user and adds data to database. Then, it retrieves a value associated to a specified ID.
Listing 8 shows the source code for the main page of this web application, which is written using a code-inline style.
Listing 8: The main page of the web application
Now, I run this application and add my values to the database. Figure 1 shows the output when I add my data to the database.
Figure 1: Adding data
Figure 2 shows the output when I select the data from the database.
Figure 2: Selecting the data
In this article I showed you how to implement the data provider model for your .NET applications and libraries. You can use it for your own needs or as a template for implementing providers for various data storage systems.
After giving an introduction and a quick overview of the process of implementing a provider model in .NET, I talked about implementing the main data provider class. Then, I talked about implementing the data provider collection and data provider configuration classes that can be used for your data provider configuration.
After that, I discussed about the data provider manager class, which is responsible for loading and using a concrete provider.
Next, I wrote a default SQL data provider for my example, to show you how easy it can be to implement a data provider model in .NET. I've then configured an ASP.NET 3.5 web application to test the provider model.
Keyvan Nayyeri is a Ph.D. student in Computer Science and already has a B.Sc. degree in Applied Mathematics.
His primary research interests are Software Engineering and Programming Languages & Compilers. He’s also a software architect and developer with a focus on Microsoft stack of developm...
This author has published 5 articles on DotNetSlackers. View other articles or the complete profile here.
Other articles in this category
Introduction to StructureMap
Have you heard of StructureMap, generally know what it’s for, and want to know how to get started qu...
DI Patterns: Constructor Injection
In this article, an excerpt from the book "Dependency Injection in .NET", we will take a detailed lo...
The Command Pattern
In this article I will provide a quick refresher on what the command pattern is used for, how it wor...
Brian Mains discusses how to implement the Arrange-Act-Assert pattern in TypeMock.
Key Process Patterns
This article, based on chapter 2 of Specification by Example, presents effective patterns for softwa...
You might also be interested in the following related blog posts
ASP.NET 4.0 Dynamic Data and Many to Many Entity Framework Entities
New content providers for the RadEditor and RadFileExplorer controls
Spec Explorer: A Model-Based Testing tool
EF4: Lazy Loading on By Default but what about pre Beta 2 Models?
Silverlight, MVVM, Prism and More at VSLive Orlando
ASP.NET MVC 2 Preview 2
RELEASED ASP.NET MVC 2 Preview 2
Html Encoding Code Blocks With ASP.NET 4
Presentation Models: Cohesion
5 Minute Overview of MVVM in Silverlight
Please login to rate or to leave a comment.