views:

1046

answers:

11

I am looking at depency injection, I can see the benefits but I am having problems with the syntax it creates. I have this example

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}

The problem is that I don't want to write

BusinessProducts bp = new BusinessProducts(dataContextImplementation);

I would continue to write

BusinessProducts bp = new BusinessProducts();

because I feel the first alternative just feels unatural. I dont want to know what the BusinessProduct "depends" on to get the products, also I feel it makes my code more unreadable.

Is there any alternatives to this approach as I would like to keep my original syntax for creating objects but I would like to still be able to fake the dependencies when unit testing or is it this dependecy injection frameworks can do for me?

I am coding in c# but alternatives from other languages is welcome

+1  A: 

http://springframework.net/ and http://structuremap.sourceforge.net/Default.htm are probably the mostly used DI frameworks for .NET based languages and will both do what you need.

Strelok
+3  A: 

There are two distinct cases here:

In production code you will never write

new BusinessProducts(dataContextImplementation)

because dependency injection will normally be creating the full object hierarchy for you. This is the "viral" nature of dependency injection patterns, they tend to take over full control of your service creation.

In unit test code you will normally be creating this yourself, but quite often you will be supplying a mock object or a stub implementation of dataContextImplementation. So normally you will be injecting an object that does not have a large number of subsequent dependencies.

krosenvold
@krosenvold -- I think you are thinking of DI frameworks, not DI the pattern. The pattern just says that you do exactly that -- inject dependencies via constructor or property setters. You can use DI the pattern without using a DI framework.
tvanfosson
A: 

you can also look at windsor for IoC .

sirrocco
+6  A: 

You can create a factory. DI containers are best for wirings that happen at setup-time - not at runtime (As this looks to be a case of). Factories can be implemented in different ways, depending on how pluggable it needs to be, and how many places you need to use it.

troelskn
+1  A: 

Generally the framework itself will have the logic to build up the entire object tree. For example, instead of

new SomeObjectO(diContext)

you would call the framework like this:

DIFramework.GetNew<SomeObjectO>();

or

DIFramework.Get<SomeObject>();

Another interesting framework to take a look at if you would like to learn about DI and the process is Microsoft's Unity and Object Builder projects.

siz
thx, this was a clarifying answer
TT
Why is it that nearly everyone answering is confusing DI the pattern with a DI framework? DI frameworks use DI the pattern, but you don't have to use a DI framework just to implement DI the pattern.
tvanfosson
I agree with you tvanfosson. This answer just helped me understand what a DI framework does for you
TT
Not saying that it wasn't useful (to you), but talking about the two as if they were the same thing is just plain confusing.
tvanfosson
@tvanfosson: Point taken. However, I was illustrating how a framework might implement the pattern. TT, although referring to the DI pattern, was asking about the interface and how the DI pattern might be implemented. The above factory methods are one way.
siz
What is a DI framework? Is it the same as IoC frameworks?
Owen
They are certainly used interchangeably. Fowler says IoC is too generic of a term a prefers to use Dependency Injection. Read more here: http://martinfowler.com/articles/injection.html
siz
+8  A: 

I use a factory for my context and inject it, providing a suitable default if the provided factory is null. I do this for two reasons. First, I use the data context as a unit of work scoped object so I need to be able to create them when needed, not keep one around. Second, I'm primarily using DI to increase testability, with decoupling only a secondary consideration.

So my business products class would look like:

public class BusinessProducts
{
     private IDataContextFactory DataContextFactory { get; set; }  // my interface

     public BusinessProducts() : this(null) {}

     public BusinessProducts( IDataContextFactory factory )
     {
          this.DataContext = factory ?? new BusinessProductsDataContextFactory();
     }

     public void DoSomething()
     {
          using (DataContext dc = this.DataContextFactory().CreateDataContext())
          {
             ...
          }
     }

An alternative to this would be to make the factory property publicly settable and inject an alternate factory by setting the property. Either way if you want to keep the null constructor, you'll need to provide a default.

tvanfosson
+6  A: 

I would usually have an empty constructor which uses a solid instance( or an instances created by IoC), amd one with DI. i.e.

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts()
   {
      _dx = new SolidDataContext();
   }

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }
}

This way you can use DI for overriding the default instance in unit testing testing.

Owen
I've used this technique several times for injecting in different implementations for the purpose of unit testing. It is useful if you don't have an DI container.
RichardOD
+1  A: 

If you really do not like injecting this instance in the constructor, you might try to use the CommonServiceLocator with your favourite compatible .NET depedency injection framework. This would allow you to write code like this:

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts()
   {
      _dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}

However, please beware that this is not what most people would expect when they know that you use a dependency injection framework. I think that it is much more common to use a dependency injection framework and letting it create all objects for you.

BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();

If you would like to avoid the dependeny injection framework path, using a factory is probably the best way to go.

hangy
+1  A: 

There's a technique called poor man's DI that looks like this

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts() : this(new DataContext()) {}

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}

This is not ideal since it ties you to the implementation but its a good stepping stone towards decoupled code. this is similar to @tvanfosson but a lot simplier.

I second the recommendation for Windsor

Scott Cowan
+1  A: 

My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.

My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)

Load the container (can be in code like I prefer or using configuration)

protected void Application_Start(object sender, EventArgs e)
{
    Application.GetContainer()
     // presenters / controllers are per request                 
     .RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())

     //Data Providers are Per session                
     .RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())

     //Session Factory is life time
     .RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}

Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.

private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
    var handler = HttpContext.Current.Handler;
    HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);

    // User Controls are ready to be built up after the page initialization is complete
    var page = HttpContext.Current.Handler as Page;
    if (page != null)
    {
     page.InitComplete += OnPageInitComplete;
    }
}

Page container presenter decorated with [Dependency] attribute

public partial class Employees : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    [Dependency]
    public EmployeePresenter Presenter
    {
     set
     {
      _presenter = value;
      _presenter.View = this;
     }
    }
}

Presenter with InjectionConstructor method

public class EmployeePresenter : Presenter<IEmployeeView>
{
    private readonly IEmployeeController _controller;

    [InjectionConstructor]
    }
    public EmployeePresenter(IEmployeeController controller)
    {
     _controller = controller;
}

Controller follows suit

public class EmployeeController : IEmployeeController
{
    private readonly IEmployeeDataProvider _provider;

    [InjectionConstructor]
    public EmployeeController(IEmployeeDataProvider DataProvider)
    {
     _provider = DataProvider;
    }
}

Same with provider

public class EmployeeController : IEmployeeController
{
    private readonly IEmployeeDataProvider _provider;

    [InjectionConstructor]
    public EmployeeController(IEmployeeDataProvider DataProvider)
    {
     _provider = DataProvider;
    }
}

Lastly the session manager, which contains only a regular constructor.

public class NHibernateSessionManager : INHibernateSessionManager
{   
    private readonly ISessionFactory _sessionFactory;

    public NHibernateSessionManager()
    {       
     _sessionFactory = GetSessionFactory();
    }
}

So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.

Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.

Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.

Chris Marisic
+3  A: 

Your feelings, while valid, are misplaced.

The Dependency Injection pattern is a direct application of the Inversion of Control principle.

This means that, instead of your class controlling the instances of other classes it consumes, that relationship is inverted and the dependencies are provided to it.

As such, your classes naturally expose their dependencies via constructor arguments or properties. Showing disdain for this structure says you haven't truly grokked the pattern.

Bryan Watts