Please note: I have just started using AutoFac to learn about DI and IoC.
Is dependency injection supposed to be initialized in the controllers constructor?
Ho
Dependency Injection means exactly injection of dependency. It does not say anything about initialization. E.g. if you are injecting dependency which is Singleton, then it can be initialized long before you are injecting it.
Your first code is a usual dependency injection via constructor. Your second code is not dependency injection. Actually it looks odd to me - either you are trying to create instance of interface, which is not possible, or you have bad naming here. If it is just bad naming or typo, then second sample should really look like:
public IMyService iMyService = new MyServiceImplementation();
But you are not injecting anything here. You are simply creating dependency instance (which makes your controller coupled to dependency implementation).
Edit, the dependency always "exists" but it was moved outside of the class
notice that IMyServices
can now be defined in the same project as HomeController
when MyService
is in totally another class. and your DLL with HomeController
can compile without knowing about your MyService
dll effectivly decoupling them.
this is a very complex topic and you should read a book about it. reading blogs videos and so on didn;t really help.
this is a good book. http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501
this is a great vidoe lecture series first 5 videos are about DI in general http://channel9.msdn.com/Blogs/mtaulty/Prism--Silverlight-Part-1-Taking-Sketched-Code-Towards-Unity
initilization is focused in a COMPOSITION ROOT http://blog.ploeh.dk/2011/07/28/CompositionRoot/
and the pattern you shown here is CONSTRUCTOR INJECTION
https://softwareengineering.stackexchange.com/questions/177649/what-is-constructor-injection
You can say that. Actually AutoFac, ninject etc. have feature for binding the interfaces with classes. So you will need to do that first. I mean to say that you will need to create one class and you will need to ask AutoFac and ninject to bind it with the interface.
So, when controller will be looking for any particular interface then AutoFac and ninject will just create object of that class and assign it to interface. And as far as initialization is concerned you can initialize the values while binding the class with interface.
private IMyService iMyService;
public HomeController(IMyServices myService)
{
iMyService = myService;
}
in this case,you only care about what you need(IMyServices)
public IMyService iMyService = new MyService();
but in this case,you care about what it will be(new MyService())
when design a class,you know what you need;
but what it will be,that not decided by you,that decided by who use your class
Dependency injection is not trivial - the concept is simple, but understanding it might require some practice and research. Let me give you an example of a place where DI is used, perhaps it will make sense (might not be the best example, sorry I can't think of anything better ATM):
So say you have the following class:
public class MyAwesomeClass {
private readonly IConfig _config;
public MyAwesomeClass(IConfig config) {
_config = config;
}
public IEnumerable<string> GetFiltered() {
IEnumerable<string> results = _config.GetSettings();
// filter my results
return results.Where(x => x.StartsWith("awesome", StringComparison.OrdinalIgnoreCase));
}
}
Now if you're to test GetFiltered
you can inject a fake implementation of IConfig
and make sure that your filter is working correctly (you isolate your code from depdendencies). You also invert the control by exposing the dependencies and letting the user of your class take care of them, you're pretty much saying - "If you want me to work I need to you to give me an implementation of IConfig
, you take care of it."
Here is how the test might look like
[Test]
public void GetsOnlyResultsContainingAwesome() {
var fakeConfig = new FakeConfig();
var awesome = new MyAwesomeClass(fakeConfig);
IEnumerable<string> results = awesome.GetFiltered();
Assert.AreEqual(2, results.Count());
}
Here is the fake implementation of IConfig
public class FakeConfig : IConfig {
public IEnumerable<string> GetSettings() {
return new List<string> { "test1", "test2", "awesome1", "awesome2" };
}
}
I hope this makes sense. Sorry if my example is not good, but I'm just trying to illustrate a point.