How to inject DbConnection into DbContext?

May 5, 2014 at 1:24 PM
I am using MVC, EF, SimpleInjector and Effort (in-memory database, using it for unit testing).

Following a tutorial on the Effort site my custom DbContext class is taking a DbConnection as constructor parameter. Being completely new to SimpleInjector (and DI in general, containers even more so), I need some help figuring out how to registering a SqlConnection to be retuerned whever a DbConnection is asked for.
May 5, 2014 at 1:32 PM
Edited May 5, 2014 at 3:21 PM
There are many ways to do this. For instance, you can register your SqlConnection as follows:
string connString = ConfigurationManager.ConnectionStrings["myConstr"].ConnectionString;
container.RegisterPerWebRequest<DbConnection>(() => new SqlConnection(connString));
The RegisterPerWebRequest extension method makes use of the WebRequestLifestyle and this ensures that the SqlConnection will be disposed on the end of the web request.

Auto-wiring your DbContext however, might not be the best thing to do, since DbContext is a framework type and constructor's tend to be added to framework types from version to version. This might cause your configuration to break suddenly after updating to a new version. Read this for more info on the subject.

So, instead you can register your DbContext with a delegate as well:
container.RegisterPerWebRequest<DbContext>(() =>
    new MyDbContext(container.GetInstance<DbConnection>());
May 5, 2014 at 3:17 PM
I assume you meant to write
container.RegisterPerWebRequest<DbConnection>(() = >new SqlConnection(connString));
since, according to intellisense, there is no constructor that takes one argument for the code you wrote?

Also, the URL in the link you posted begins with bad stuff.

Thanks, I will have a look at the blog. Now it works and I am happy. Always an icky feeling using new things since it is hard / impossible to know good practices,
May 5, 2014 at 3:22 PM
You are right, You need to do RegisterPerWebRequest<DbConnection>(() => ...). I updated my answer and updated the link as well.
May 24, 2014 at 2:30 PM
I apologize for waking up this thread but I have been away doing other things and just got back to this.

I have some trouble understanding the second part of your first post, the one starting with "Auto-wiring your DbContext however...". I have read the blog that you linked and the blog entry make sense to me. I cannot understand how to ... make it work though. I am missing something basic here.

You wrote: "So, instead you can register your DbContext with a delegate as well:"
The "instead" part I interpret as though we do not register a DbConnection, but instead register a DbContext. Is that correct? Cannot be, since DbConnection is an abstract class, no? If so, we still need to register DbConnection, which is bad for the reasons outlined in the blog. But then the whole point of registered a DbContext as well is moot. Hrms. What am I not understanding here?
May 24, 2014 at 3:01 PM
I didn't mean that you should register the DbContext instead of the DbConnection, although registering the DbConnection itself might not be a good idea. If you supply a DbConnection to a DbContext, it will open and close that connection for you. This might break in surprising places if you inject a connection in other services as well (services that need to interact directly with the DbConnection, instead of going through the DbContext).

So instead of registering a DbConnection, you might be better of registering an IConnectionFactory class. Services that need a connection to the database can depend on that factory and request a new connection from the factory AND dispose that connection directly after use. You can even go through the IConnectionFactory when creating a new DbConnection as follows:
container.RegisterPerWebRequest<DbContext>(() =>
    new MyDbContext(container.GetInstance<IConnectionFactory>().CreateNew());
When registering a DbContext in the applications I build however, I never supply the DbContext with a connection. Instead I pass in a connection string directly and let the DbContext itself manage the DbConnection.
Marked as answer by dot_NET_Junkie on 5/30/2014 at 2:21 AM
May 24, 2014 at 3:43 PM
I see. Thanks for the detailed reply.

I do not thing using a connection string is an option for me if I want keep using Effort for unit testing my repository methods, so I guess the option is to either go with the connection factory or to use some other method of testing the repositories.