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?
When shouldn't I use a dependency injectors?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With