IoC and ASP.NET MVC, where does it all begin?
I see "IoC" and "DI" mentioned pretty much everywhere for ASP.NET MVC. While I'm well aware of ... 'kind of' what these are, it's one of those almost ambiguous, amorphous floating concepts that seems to have either passed me by, or I'm just not looking in the right place. With the upcoming release of ASP.NET MVC 3.0, I'm seeing it even more. So much so that it feels like it's an entire part of programming I simply don't know about.
I've tried looking for books on the subjects, but most of what I find seems to make a lot of assumptions (history in Ruby, understanding what it is but not how to use it, etc).
I'm just asking upfront and plain. What is IoC, and why do I care about it? Are there any decent websites that cover this from a beginner programmer perspective? Assume I know nothing about it. Assume I know nothing but C#. I read every book, blog, and tutorial on C# from .NET 1.1 to .NET 2.0, and when .NET 3.5 and LINQ hit, it just became so much to handle that I couldn't keep up. I am a rookie developer working in ASP.NET MVC/C# and I can't help but feel I am missing something very important. (I'm having a lot of the same feelings about DI (dependency injection))
I've googled, I've read blogs, I've seen Castle.Windsor
, I've seen sample code, I've browsed books and webcasts, and I'm still so in the dark. It feels like one of those inside stories at work that you know you should know about, but for some reason, you don't, and school didn't really prepare me for it.
StackOverflow has always shown to be the best of the best in the development community for me. 开发者_运维百科Through college and introductory work, and low-level freelance work, I have amalgamated my education on programming from other programmers (though as I understand it that is not neccessarily something to be ashamed of). So once again, I am simply stating to the community.
Huh? I don't understand.
Speaking with many of my colleagues that are trying to break into the same field, many of them feel the same way. So I can't help but feel somewhere along the line, us 'newbie' programmers missed the memo of these conceptual approaches to coding. I'd like to not only get this question answered, but I think a good thread for other people like myself who are trying to understand it might be an intelligent idea (and if one exists, it needs to be made more obvious)
Some of what I have found that has been helpful has been http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection and http://www.dotnetspark.com/kb/1222-inversion-control--beginner-guide.aspx
But I am still left scratching my head on a number of issues as to why this is important. Truthfully, I feel that a large part of the developer community actually feels this way about both IoC and Unit Testing. Very little lays out what it is and the examples discovered are usually pretty poor, or very hard to understand. When .NET was introduced, it was stand-alone. I didn't need a bunch of other concepts to make simple programs run. Now, .NET is a respected language, and everything under the sun is adopting it (nHibernate, MVC, MVP, MVVP, Clouding platforms, gaming architecture, etc)
(Please feel free to point out if I am just flagrantly wrong. I am not calling myself 'good' by any means. But I know C#, and I know it very well. I consider myself a very fast learner and as hard a time as I am having with this I just have to assume that there is some 'hole' out there that needs to be filled)
Let's keep all the IoC frameworks aside and discuss the concept. IoC is not a new concept and has been around for a long time. IoC is basically implemented to make your system loosly coupled to certain subsystem. We achieve decoupling by extracting out common/core behavior of subsystem into a contract. Contract is usually in shape of interface. Now you depend on this interface. You are not worried about how a particular system concretely gives you the behavior that you are after.
Recently I had real life encounter with this. We are having one existing payment system and then we are developing a new payment system to adhere to PCI. What you do in these kind of situation is that you extract the common features of both systems in an interface and then your application interacts with these two systems only via interface. You can either use a flag in config file or factory pattern or ultimately an IoC framework to inject this dependency in your application. At runtime your application will get the object that it depends on. You need DI/IoC in an environment where uncertainty is there regarding the use of any given subsystem due to any reason. In this example new payment system couldn't get delivered on time and hence my application needed a configurable option to switch between any system at runtime. If I don't do IoC, I will have to do code change every time business changes their mind.
Another need of IoC is to do TDD. Same thing that I described above can be used to develop a mock implementation of real application and can be used to do testing while real component is still in development.
Dependency Injection is a good book to start with. You can also download a free paper on DI from the same author here.
Update: Adding code for more clarity
public interface ITest
{
void Hello();
}
Now I can have two different concrete implementations:
public class Hi : ITest
{
public void Hello()
{
HttpContext.Current.Response.Write("Hi there!");
}
}
public class HelloMessage : ITest
{
public void Hello()
{
HttpContext.Current.Response.Write("Hello there!");
}
}
ITest messenger;
if (User Needs "Hi")
{
messenger = new Hi();
}
else if (User Needs "Hello")
{
messenger = new HelloMessage();
}
messenger.Hello();
All my application has to do is call the method available in contract. Right now application is handling the dependencies explicitly but is free of any concrete implementation. However it is still tied to these two concrete implementations. IoC frameworks helps us to outsource this job to a configuration file. There I can provide any other concrete implementation regardless of how it is implemented and application will continue to work without any code change.
Following is the code where I am using Unity 2 and outsourcing explicit handling of dependencies on my own.
using (IUnityContainer container = new UnityContainer())
{
container.LoadConfiguration();
ITest messenger = container.Resolve<ITest>();
messenger.Hello();
}
Config for the same:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<assembly name="Injection"/>
<container>
<register type="Injection.ITest" mapTo="Injection.Hi"/>
</container>
</unity>
HTH
For some video intros, check out DimeCasts.net.
The main two reasons I like Ioc:
- Easier Unit Testing.
- Easier to swap out backend data to test. Say you have a IPersonRepository. Your code implements a PersonRepository that loads data from the database. But what if you don't have any data in the database or the database isn't set up yet? You use IoC to implement a DummyPersonRepository that will load the data from somewhere else, like an XML file, or hardcoded data.
I think you will begin to grasp IoC/DI stuff when you understand why and when it is used. I wouldnt worry too much about which IoC container to use. You could essentially write a basic container yourself (At the most basic level its is just a Dictionary that maps an interface to a concrete implementation ). Here is a good video showing how that would be done.
The core concept is that it encourages loose coupling of components, which means code is easier to test and does not depend on other concrete classes.
This link has details about the SOLID principles, your question particularly pertains to the "D" (Dependency Inversion Principle), but the others will also be of interest.
精彩评论