Wrap It in a Factory
As an added bonus, let me show you a really cool way you can wrap all the code that determines what provider to use, instantiates it, casts it, and accesses the interface members into a static (shared) factory class. This is the same pattern that ASP.NET uses with its Membership, Roles, and Profile classes. Describing the Membership class should give you a good feel for what I'm going to do in the application example.
In ASP.NET, you can create a user using the Membership class, using:
all arguments here...
ASP.NET uses a provider model behind the Membership class in order to determine how it will create a user. When you execute a statement like the one above, you execute the static constructor of the Membership class. At that point, the application reads the app.config
and makes the decision as to what provider to use. By the time you call the CreateUser
method, the class has a member variable that you've declared as the membership abstraction (in this case, a base class called MembershipProvider) and instantiated as the appropriate provider class as defined in the app.config
. The CreateUser
method delegates the call to the CreateUser
method of said variable, which executes the appropriate implementation. That's what I'm going to do with the provider model.
So here are the steps:
- Create a class that will contain static (shared) members only.
- Declare a class-level private static variable of type IDataProvider.
- In the static constructor, execute the code that will fill the static IDataProvider variable.
- Set up static methods that mimic those of the IDataProvider interface.
- In each of the methods, call the corresponding method in the IDataProvider variable.
For example, if I called my class AcmeFactory, it would look like this (note that Visual Basic modules behave like C# static classes)
' In VB:
Public Module AcmeFactory
o_Provider = GetDataProvider()
Private o_Provider As IDataProvider = Nothing
Public Function GetDataProvider() As _
Dim s_Provider As String = _
Dim o As Object = _
o_Provider = DirectCast(o, IDataProvider)
Public Function GetSource() As String
Public Function GetData() As String
Dim s_Source As String = o_Provider.GetSource()
Dim s_Data As String = _
Public Sub LogData(ByVal data As String)
// In C#:
public static class AcmeFactory
o_Provider = GetDataProvider();
private static IDataProvider
o_Provider = null;
public static IDataProvider
string s_Provider = ConfigurationManager.AppSettings[
Object o = Activator.CreateInstance(
o_Provider = o as IDataProvider;
public static string GetSource()
public static string GetData()
string s_Source = o_Provider.GetSource();
string s_Data = o_Provider.GetData(s_Source);
public static void LogData(string data)
Now, to actually use the provider, the client simply has to do the following:
' In VB:
Dim s_Data As String = AcmeFactory.GetData()
If s_Data <> "" Then
// In C#:
string s_Data = AcmeFactory.GetData();
if (s_Data != "")
Note that the code doesn't even call the GetSource
method here; instead, GetData
does that for me in the factory class.
You can inject the provider model in many places throughout an application. If you ever find yourself looking at a piece of code and wondering if it may ever be subject to change, think about using this pattern there. If you ever find yourself looking at a process and wondering if it may be one day swapped out, removed, or enhanced, you may want to look at a plug-in model.