This project is read-only.

DataAccessProvider Explained

Aug 29, 2009 at 10:02 PM
Edited Sep 26, 2009 at 7:12 PM

Every environment is different when it comes to database connectivity and multiple environments.  .NET provide a quick and dirty means of configuring connection strings through <connectionString> attribute in your application configuration file.  However, this type of configuration "exposes" connection strings to all developers and forces it to be manually manipulated when code is migrated across multiple environments.  This responsibility is usually transfered over to individual(s) responsible for code migration and is typically prone to errors (e.g. "oops...we forgot to update the config file"). 

SEAM provides a flexible approach to creating and securing your connection strings while adhering to a concept of a simple API for developers during development phase.  If implemented appropriately, the need for manual intervention while migrating code can be eliminated through the use of SEAM's IDataAccessProvider interface.  Additionally, SEAM also provides a level of abstraction from the physical database implementation.  Developers no longer need to code against SQL Server or Oracle (using ADO.NET).  Interactions to the database are conducted through DataAccess class provided in SEAM.Data.  As a result, migrating from one DBMS to another (e.g. SQL Server to Oracle) can be a task exclusively on the database end.  A simple change to your implementation DataAccessProvider will change all calling code to use appropriate drivers and ADO.NET code.*

Below are few examples of how IDataAccessProvider should be implemented under different scenarios:

Scenario # 1:  your environment consists of 3 environments (development, QA, and Production) running two types of SQL Servers (read-write and read-only).

If you are working within a "small environment", you may find that you have two entries (typically unencrypted) in <connectionString> section of the application's configuration file.  Additionally, the same two entries would be repeated within every application that interacts with the two databases.

<configuration>
  <connectionStrings>
<!-- TODO: Change connection strings with each environment --> <add name="ReadOnly" connectionString="Data Source=DevServerRO;Integrated Security=True;" /> <add name="ReadWrite" connectionString="Data Source=DevServerRW;Integrated Security=True;" /> </connectionStrings> </confconfiguration>
// The usage may look something like this...
using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ReadOnly"]))
{
// Do stuff here...
}

In a "slightly bigger environment", it is very likely that your applications has an environment "token" in your configuration file and a class that allows you to retrieve the connection string (e.g. ConnectionManager class) that you would use to retrieve the connection string through some sort of a factory method such as ConnectionManager.GetConnectionString(ConectionType.ReadOnly).  The class would some how "lookup" the appropriate connection string and return it to the caller.  However, in most cases, the caller's code would assume that the connection being made is to a SQL Server. Below may be a typical implementation:

<configuration>
  <appSettings>
    <add key="Environment" value="DEVELOPMENT"/>
  </appSettings>
</configuration>
public class ConfigurationManager
{
    public static string EnvToken
    {
        get { /* get token from config file and return it */ }
    }

    public static string GetConnectionString(ConnectionType conType)
    {
        if (EnvToken == "DEVELOPMENT")
        {
            if (conType == ConnectionType.ReadOnly)
                return "Data Source=DevServerRO;Integrated Security=True";
            else
                return "Data Source=DevServerRW;Integrated Securit=True";
        }
        // Check for other environments and return right connection
}
}

// The usage may look something like this...
using (SqlConnection conn = new SqlConnection(ConnectionManager.GetConnectionString(ConnectionType.ReadOnly))
{
// Do stuff here...
}

SEAM provides flexibility to support both types of situations while keeping the development abstracted from working with SQL Server directly (e.g. SqlConnection) and keeping ADO.NET code to a minimum in your application. The implementation of DataAccessProvider is completely in your hand; therefore, you can build whatever flexibility that you need. You can decide to implement SEAM using the same situation as above (and actually reuse the same code that you may have written) in creating your DataAccessProvider;

 


* Note: any inline sql statements (through the use of DataAccess.Query(...) methods) must be validated manually to ensure adherence to the appropriate DBMS standards.