views:

148

answers:

2

I'm new to dependency injection, I'm wondering how you would handle the following scenario. We have something like the following:

public class DatabaseContext
{
  public string ConnectionString {get;}
}

public interface IDataAccess
{
  string GetString(int id);
}

public class DataAccessImpl : IDataAccess
{
  private DatabaseContext _context;
  public DataAccessImpl(DatabaseContext context)
  {
    this._context=context;
  }

  public string GetString(int id)
  {
    return "some data";
  }
}

For web applications each request could build up a different DatabaseContext to point to a different database. For windows forms we could change the current DatabaseContext. How does a di framework handle a dependency that can change? Such that when i request a IDataAccess it always has the appropriate/current DatabaseContext.

A: 

A Dependency Injection (DI) framework is designed to break coupling.

One part of you application 'injects' a service that implements an interface into the DI container.

Another part of your application 'asks' the container for the implementer of a given interface. It doesn't 'know' who the concrete implementor of the interface is.

Mitch Wheat
+1  A: 

The approach that I've taken is not to inject a DataContext but a DataContext factory, a class with a method that returns a DataContext of the appropriate type. I have two constructors for, in my case, a controller class the default constructor and one that takes the factory (and other injected objects). The default constructor simply calls the constructor with parameters with all the parameters null. The parameterized constructor creates objects of default types if the corresponding parameter is null.

Using the factory allows my controller actions to create a new DataContext when invoked instead of having a single DataContext that exists throughout the life of the application. The factory could be built to return an existing context if available and create a new one as needed, but I prefer to scope them to a unit of work.

P.S. The factory actually produces a wrapper class around a DataContext, not the actual DataContext, as an interface (IDataContextWrapper). This makes it much easier to mock the actual database out of my controller tests. All of the above assumes LINQ/ASP.NET MVC, but the principles are generally applicable, I think.

tvanfosson