Introduction
In a previous tutorial, we created an abstract class for basic SCRUD database operations. Today we’re going to build on that to create a generic database abstraction layer (DAL). The aim of this is to allow you to connect to any database type without having to worry about changing your Data Layer classes.
We’re also going to be introducing 2 of the most common design patterns.
Factory Singleton
First download the previous tutorial source code from here. We’ll be creating 2 new classes for this tutorial
DatabaseProvider.cs
This class will serve as our configuration class for the database connection. It will define the basic properties and methods that we will need to successfully initialize and load our chosen connection dll using Reflection
DatabaseFactory.cs
The factory class will read our configuration and based on that locate and load our connection.
Step 1 – DatabaseProvider.cs
The main interface that we care about when creating our DAL is:
IDbConnection
When using reflection to load our database provider, this is the interfaces we will be looking for.
private static readonly Type CONNECTION_TYPE = typeof(IDbConnection);The first method we are going to implement will tell us if the dll we have loaded actually implements the methods we need. If it doesn’t we can move on to the next dll. This method will be called from inside the factory on initialization.
public static bool IsDatabaseProvider(Assembly assembly) { bool returnValue = false; try { foreach (var type in assembly.GetTypes()) { returnValue = (type != CONNECTION_TYPE && CONNECTION_TYPE.IsAssignableFrom(type)); if (returnValue) break; } } catch (Exception) { //We can ignore this } return returnValue; }Here we’re using reflection to confirm the interfaces that a particular dll implements, if we find a match for our CONNECTION_TYPE and if it can be initialized we can use it. If the dll does not have the required interface, we’ll ignore it.
Now that we can identify our database provider, we can complete the rest of our wrapper class. First up is the constructor and setting up our properties.
public string Name { get; private set; } public string FullName { get; private set; } public Assembly Assembly { get; private set; } public Type ConnectionType { get; private set; } public DatabaseProvider(Assembly assembly) { this.Assembly = assembly; this.Name = Assembly.ManifestModule.Name.Replace(".dll", ""); this.FullName = Assembly.FullName; foreach (var type in assembly.GetTypes()) { if (type != CONNECTION_TYPE...