Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a DbProviderFactory without an App.Config

I am using DbProviderFactories in my data layer (based on Entity Framework) and am using SQLite for my database, but I don't have to have a App.Config to have the following code:

<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite"/>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>

Instead I would like to have my data layer put that in programmatically. Anyone know a way to do this?

EDIT:

The reason for this is that I am using a IoC container to pick the data layer and some of my data layers don't need the App.Config values, or have them be hard tied to the data layer.

like image 896
JasonRShaver Avatar asked Jul 13 '09 04:07

JasonRShaver


3 Answers

The following will probably cause sunspots and overthrow western civilization. It may even cause a debate about Duct Tape Programming (make it stop!), but it works (for now)

try
{
    var dataSet = ConfigurationManager.GetSection("system.data") as System.Data.DataSet;
    dataSet.Tables[0].Rows.Add("SQLite Data Provider"
    , ".Net Framework Data Provider for SQLite"
    , "System.Data.SQLite"
    , "System.Data.SQLite.SQLiteFactory, System.Data.SQLite");
}
catch (System.Data.ConstraintException) { }
like image 174
JoshRivers Avatar answered Sep 30 '22 18:09

JoshRivers


JoshRivers above posted a solution for SQLite. This can in fact be used for other adapters as well- I was able to get it working for MySQL using his example. I have wrapped this into something a bit more generic. This should be run once the application starts and is for the .NET connector version 6.6.5.0 (but I imagine it is good for other versions as well.)

string dataProvider = @"MySql.Data.MySqlClient";
string dataProviderDescription = @".Net Framework Data Provider for MySQL";
string dataProviderName = @"MySQL Data Provider";
string dataProviderType = @"MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d";

bool addProvider = true;
var dataSet = ConfigurationManager.GetSection("system.data") as DataSet;
foreach (DataRow row in dataSet.Tables[0].Rows)
{
    if ((row["InvariantName"] as string) == dataProvider)
    {
        // it is already in the config, no need to add.
        addProvider = false;
        break;
    }
}

if (addProvider)
    dataSet.Tables[0].Rows.Add(dataProviderName, dataProviderDescription, dataProvider, dataProviderType);
like image 29
A.Konzel Avatar answered Sep 30 '22 18:09

A.Konzel


LATE ANSWER:

You can always directly get a factory like this:

DbProviderFactory factory = System.Data.SQLite.SQLiteFactory.Instance;
// (note that the rest of the code is still provider-agnostic.)

Or use your IoC container to resolve the DbProviderFactory, e.g.:

container.RegisterInstance<DbProviderFactory>(SQLiteFactory.Instance);

I prefer not to use the DbProviderFactories.GetFactory because of its limitation of requiring a configuration file (or a hack like in @JoshRiver's answer).

All DbProviderFactories.GetFactory does is, it looks up the registered assembly-qualified name of the factory type using the provider name, and then it gets the value of the static Instance property using reflection.

If you don't want to use the configuration, one of the methods above might be more convenient depending on your use case.

like image 20
Eren Ersönmez Avatar answered Sep 30 '22 18:09

Eren Ersönmez