Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use dependency injectors like Ninject

Problem

I have some problems to understand when and where exactly in my code I should use dependency injectors like Ninject.

Code

Let's say for example we have the following code:

//WITHOUT NINJECT:     
IMailSender mailSender = new MockMailSender();

//WITH NINJECT:
IMailSender mailSender = kernel.Get<IMailSender>();

This one is not a dependency injection so does it make sense to use Ninject in this scenario?

Another example shows how my code gets really messed up by using a dependency injector:

 public void CalculateRevenueRecognitions(IContract contract)
    {
        //WITH NINJECT
        var kernel = new StandardKernel(new DefaultModule());
        var arguments = new List<IParameter>
        {
            new ConstructorArgument("amount",contract.Revenue),
            new ConstructorArgument("date", contract.WhenSigned)
        };
        contract.AddRevenueRecognition(kernel.Get<IRevenueRecognition>(arguments.ToArray()));

        //WITHOUT NINJECT:
        contract.AddRevenueRecognition(new RevenueRecognition(contract.Revenue, contract.WhenSigned))));
    }

Question

When should I use a dependency injector?

  1. on constructor injections, parameter injection, etc.
  2. on object creation (do dependency injectors replace classical object creation with new?)
  3. are the others?

When shouldn't I use a dependency injectors?

like image 479
MUG4N Avatar asked Dec 21 '22 01:12

MUG4N


1 Answers

The basic premise is to not rely on concrete classes (like you said newing concrete classes) and to inject implementations (via interfaces). It depends on the specific task you're performing and under what conditions (Windows Service, WCF service, Asp.Net), but in most instances you have an interface with all the methods you wish to expose publicly, like so

public interface IBar {
    void DoStuff();
}

Then you then bind these to a specific class using Ninject i.e.

 Bind<IBar>().To<BarClass>();

So at startup Ninject goes and gets the configured implementation. The plus side to this is your implementation is configured, so it's really easy to swap to another implementation as long as it's implementing the interface. So if you had another class you wanted to now use instead of BarClass, you could just rebind to it i.e.

Bind<IBar>().To<NewBarClass>();

So wherever you need to use this NewBarClass, you'd pass it in like this

public class UserOfNewBarClass {

public UserOfNewBarClass(IBar newBarClass) {
}
   // Use the IBar interface
}

Also, you can mock out the interfaces when testing which means you can isolate single concrete classes and test them in complete isolation. You can do more complex things, which you can learn later like binding based off property values and conditional binding on what you're injecting into.

For entry points consult these

WCF - http://www.aaronstannard.com/post/2011/08/16/dependency-injection-ninject-wcf-service.aspx

MVC - http://www.shahnawazk.com/2010/12/dependency-injection-in-aspnet-mvc-3.html

Windows Service - Using Ninject with a Windows Service

It's quite hard to understand at first but the Container (in this case Ninject) figures out what implementation to inject based off the binding you specify . The end goal is to inject everything your class needs in order to perform it's methods so you can test it in isolation (it also helps keep the class clean and uncluttered). The preferred way is injection via constructor as the class will have all of its dependencies when it's created. Property injection is of course doable but as with properties, you can't really guarantee it to have been set.

like image 62
Mark Walsh Avatar answered Jan 01 '23 02:01

Mark Walsh