Search code examples
mappingdatabase-connectionninjectsql-server-2008-express

Ninject: Provide an un-opened SqlConnection when asked for DbConnection


I want to map DbConnection to an un-opened SqlConnection using Ninject. This is what I've done:

string constr = @"Server=.\SQLEXPRESS; Trusted_Connection=True; Database=TestDB";

Bind<DbConnection>().To<SqlConnection>()
    .Using<OnePerRequestBehavior>()
    .WithConstructorArgument("connectionString", constr);

However, when trying to use the db I get an error saying that

This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection.

(The same operation works if I just provide the connection with new SqlConnection(constr)...)

It turns out the QueryString property of the SqlConnection I was given by Ninject is empty. What am I doing wrong?


UPDATE

I have now tested with kernel.Get<DbConnection>() directly after the binding, and with the above code it still gives me an empty connection string. The following works, although it is more verbose than I want it:

Bind<DbConnection>().ToMethod<SqlConnection>(ctx => GetConnection());

private SqlConnection GetConnection()
{ return new SqlConnection(constr); }

UPDATE 2

This is my entire module:

public class MsSqlModule : StandardModule
{
    private string constr = @"Server=AASLOEG\SQLEXPRESS; Trusted_Connection=True; Database=Booking_Test";// System.Configuration.ConfigurationManager.ConnectionStrings["mssql"].ConnectionString;

    public override void Load()
    {
        Bind<DbConnection>().To<SqlConnection>().WithConstructorArgument("connectionString", constr);
        var test = Kernel.Get<DbConnection>();
        test.Dispose();
    }
}

With a breakpoint on var test = Kernel.Get<DbConnection>(); and stepping over, I see that test is populated with an SqlConnection, but the ConnectionString property is empty.


Solution

  • I ended up solving this by creating a custom provider, and binding to it. (I've also upgraded to Ninject 2.0, which might affect the results...)

    public class MsSqlConnectionProvider : DbConnectionProvider<SqlConnection>
    {
        public string ConnectionString { get { return TestConnectionString; } }
        public string ConnectionStringFromConfigFile { get { return System.Configuration.ConfigurationManager.ConnectionStrings["mssql"].ConnectionString; } }
        public string TestConnectionString { get { return @"Server=AASLOEG\SQLEXPRESS; Trusted_Connection=True; Database=Booking_Test"; } }
    
        protected override SqlConnection CreateInstance(IContext context)
        {
            return new SqlConnection(ConnectionString);
        }
    }
    
    public class MsSqlModule : NinjectModule
    {
        public override void Load()
        {
            Bind<DbConnection>().ToProvider<MsSqlConnectionProvider>();
        }
    }