Download Provider Model C# code
The Provider Model is a design pattern allowing your application to work with different implementation to the same problem. This makes your application extensible and can easily work with various ways of interacting with a set of data through configuration.
An example would be to allow your application to work with data existing in an MS SQL, MySQL, and XML data. Your application will interact with each of these set of data through a particular provider. The great thing about this is that your application is extendible by others now. For instance another developer could code an Pointbase provider.
The following class diagram shows the classes implemented:
Overview
There are at least 6 files that need to be created/modified to fully implement a provider model in your application.
Configuration file
There is no difference between the configuration between a web-based application or a windows-forms.
Provider Configuration
This class provides access to the provider settings collection of data. Each provider setting is information about your data provider such as Name, Type and various parameters. This class is usually used only the Provider manager however in my example, I’m providing direct access to the provider settings collection through a property in the provider manager.
Provider Collection
This is a convenience class providing an indexer to get a provider class by the configured string name.
Provider Manager
This class is a singleton class that has initialized the default provider and the provider collection.
Provider
This is an abstract class that provides a method signatures to be implemented in all sub-types.
Concrete provider class
There is at least one of this kind of class. In the example provided below, there are two classes MySQLDataProvider and MyXMLDataProvider that inherit from the Provider class and potentially could implement its abstract methods.
More in depth
Configuration data
Perhaps the first to add is configuration data about your providers in either App.Config or Web.Config. The following snippet shows the proper configuration elements placed within the <configuration> element.
<configuration>
<configSections>
<section name="MyProviders"
type="Blog.Joubin.Ca.Providers.MyProviderConfiguration, ConsoleProviderModel"/>
</configSections>
<MyProviders default="SQLProvider">
<providers>
<add name="SQLProvider"
type="Blog.Joubin.Ca.Providers.Instances.MySQLDataProvider, ConsoleProviderModel"
connectionString="Data Source=.\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI;"/>
<add name="XMLProvider"
type="Blog.Joubin.Ca.Providers.Instances.MyXMLDataProvider, ConsoleProviderModel"
fileLocation="c:\temp\"/>
</providers>
</MyProviders>
</configuration>
Provider Configuration class
This class inherits from the System.Configuration.ConfigurationSection class. It exposes various configuration data through its properties. This class is utilized in the Provider Manager class and it will be initialized in the manager class.
The code provided below has a string property that names the default configured provider. Another property of this class is a collection of System.Configuration.ProviderSettings. The first default provider name property could have easily been replaced with a property exposing the default ProviderSetting object.
using System.Configuration;
namespace Blog.Joubin.Ca.Providers
{
public class MyProviderConfiguration : ConfigurationSection
{
// Represents a collection of System.Configuration.ProviderSettings objects.
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get
{
return (ProviderSettingsCollection)base["providers"];
}
}
[ConfigurationProperty("default", DefaultValue = "SQLProvider")]
public string DefaultProviderName
{
get
{
return base["default"] as string;
}
}
}
}
Provider Collection class
This class inherits from System.Configuration.Provider.ProviderCollection class. The sample code hides the “this” indexer method and returns type of your provider class.
using System.Configuration.Provider;
namespace Blog.Joubin.Ca.Providers
{
public class MyProviderCollection : ProviderCollection
{
// Return an instance of DataProvider for a specified provider name
new public MyDataProvider this[string name]
{
get { return (MyDataProvider)base[name]; }
}
}
}
Provider Manager class
This a singleton class that reads the configuration file, initializes the provider configuration and collection classes above. This class could also expose a property that returns the provider collection. In my sample code, I’m also providing another convenient property that allows user to have access to the System.Configuration.ProviderSettingsCollection which essentially is a copy of the data in the configuration file.
Your application uses the Provider manager class to get access to the default provider as well as to the provider collection.
using System.Configuration;
using System.Web.Configuration;
namespace Blog.Joubin.Ca.Providers
{
/// <summary>
///A singleton class that manages the providers collection
/// </summary>
public class MyDataProviderManager
{
static MyDataProviderManager()
{
Initialize();
}
private static MyDataProvider _default;
/// <summary>
///Returns the default configured data provider
/// </summary>
public static MyDataProvider Default
{
get { return _default; }
}
private static MyProviderCollection _providerCollection;
/// <summary>
/// Returns the provider collection
/// </summary>
public static MyProviderCollection Providers
{
get { return _providerCollection; }
}
private static ProviderSettingsCollection _providerSettings;
public static ProviderSettingsCollection ProviderSettings
{
get { return _providerSettings; }
}
/// <summary>
///Reads the configuration related to the set of configured
///providers and sets the default and collection of providers and settings.
/// </summary>
private static void Initialize()
{
MyProviderConfiguration configSection = (MyProviderConfiguration)ConfigurationManager.GetSection("MyProviders");
if(configSection == null)
throw new ConfigurationException("Data provider section is not set.");
_providerCollection = new MyProviderCollection();
ProvidersHelper.InstantiateProviders(configSection.Providers, _providerCollection, typeof(MyDataProvider));
_providerSettings = configSection.Providers;
if (_providerCollection[configSection.DefaultProviderName] == null)
throw new ConfigurationException("Default data provider is not set.");
_default = _providerCollection[configSection.DefaultProviderName];
}
}
}
Abstract Provider class
This is an abstract class defining the to-be-implemented methods in the concrete sub-types. In my example, I’m providing a single abstract method (GetUserTypes) that are implemented in the MySQLDataProvider and MyXMLDataProvider classes.
using System.Configuration.Provider;
using System.Collections.Generic;
namespace Blog.Joubin.Ca.Providers
{
public abstract class MyDataProvider : ProviderBase
{
// abstract methods that are to be concretely implemented in the Provider classes
public abstract ICollection<string> GetUserTypes();
}
}
Concrete provider classes
This is where you or another developer can extend your application by writing more providers. In my example, there will be two concrete classes, MySQLDataProvider and MyXMLDataProvider. However this can be easily extended to cover let’s say Oracle provider, MySQL or Pointbase providers.
The following code snippet is from MySQLDataProvider:
using System.Collections.Generic;
namespace Blog.Joubin.Ca.Providers.Instances
{
public class MySQLDataProvider : MyDataProvider
{
// implement the abstract methods from MyDataProvider
public override ICollection<string> GetUserTypes()
{
return new List<string>();
}
}
}
The entire code base could be downloaded:
