Dependency Inject Sql Connection? Dependency Inject Sql Connection? sql sql

Dependency Inject Sql Connection?

Technically, Wim Hollebrandse has already answered your question, but I just wanted to point out that I would personally do it another way because I don't like having to pass the connection string in each time I instantiate the class. I realize that you have a default constructor, but I think we could make this a little cleaner, still.

First, I'd create a static class for getting your connection, as follows:

public static class ConnectionFactory{    public static IDbConnection GetConnection()    {        return GetConnection(ConfigurationManager.ConnectionString["GeoDataConnection"]);    }    public static IDbConnection GetConnection(string connectionString)    {        return new SqlConnection(connectionString);    }}

Then, I'd use it like this:

public class GeoData{   public List GetCountries()   {      using (IDbConnection con = ConnectionFactory.GetConnection())      {        //Sql stuff to return countries from a database      }   }}

With this approach, if the default connection string changes, you need only change one line of code, rather than going to each line that referenced the connection string from your configuration file. It does, however, provide you with the ability to override the connection string, if necessary.

Hope that helps...

Simple, you don't need a framework. Just have an overloaded constructor for your GeoData class.

GeoData geo = new GeoData(yourConnString);

The string is your dependency. As it is not a complex type, you got your dependency injection right there.

DI is no rocket science, though some may like you to believe that.

The first question to ask yourself is what is GeoData? In other words, what is the class's responsibility?

It appears to be part of the Domain Layer, and as such might contain business logic. It may be used by (coupled to) other classes.

If that's the case, what are the dependencies? One way of determining this is by attempting to write unit tests that test GeoData in isolation. If testing requires significant setup, the class under test is either tightly coupled to other classes or has multiple responsibilities (low cohesion).

Let's say we change the class so that the constructor takes a connection string parameter. How can we test the public GetCountries method? Well, first we set up a database with known test data...

That's time-consuming and fragile (what if someone updates the data?), and the test will run relatively slowly (it has to connect to the database).

Well, we could pass in an object implementing IDbConnection to the constructor (constructor injection). Note that dependency injection normally involves passing in interfaces or abstract classes. To test it, we'd have to create a fake IDbConnection. We could use an isolation (mocking) framework. But then we'd need it to create a fake IDbCommand when CreateCommand was called...

To quote Jeremy Miller (author of StructureMap) "It’s too much effort for too little gain." See his article Best and Worst Practices for Mock Objects.

One possibility is to use the Repository Pattern. You would pass in an interface to the specific repository to the GeoData constructor. This would be easy to fake (manually or with a mocking library) for testing. The concrete repository would handle all the data access. It could be combined with an ORM framework to further abstract the data access. Connection string management would be done through the ORM or through the repository (preferably in another dependency or a base class).

If this sounds complex it's because it is. You picked one of the most difficult cases for Dependency Injection (which, unfortunately, is also one of the most common).

Dependency Injection by itself is a fairly simple concept. If your class is calling a Web Service, you can place the Web Service code in a separate class that does nothing else, implement an interface, and pass that interface to your original class. DI/IoC container frameworks can make this easier to do if you have a lot of classes and/or dependencies, but they aren't a requirement.

EDIT: Just to be clear, Dependency Injection is not the complex part. Separating the data access is.