views:

194

answers:

3

DI/IOC: There are so many frameworks and the examples quickly get sticky with details particular to that framework. I find that I often learn a new technology best if I can learn its principles outside of a framework (the forest obscuring the trees).

My question: What are the simple principles of DI/IOC? I am looking for a (framework agnostic) building approach that outlines what is gained, what the options are, what the costs are, for each simple principle. Please don't just paste links unless they actually address my question. I keep getting lost in those forests ;}

Second question: Once I understand the core principles, would it be worth building my own simple framework? IE, would the insight gained be valuable relative to the effort expended?

Thanks in advance! Robert

+2  A: 

This is a somewhat dated but good overview Inversion of Control

To me the underlying principles that drive Ioc are the concepts of components, modularity, loose coupling, cohesion. This means that you design software that is broken up into cohesive, modular units with clear dependencies, or links to other units. This is a basic principle of engineering in any field, not just programming. Once you have modularity, to create a functional system you need a way to link these components so that they form a functional whole. IoC/DI frameworks are components that abstract this concept of linking, and allow you to write code that declares links between components, and then have the ability to execute these links. The "inversion" part comes from the fact that the components themselves no longer link to their dependencies, instead the linking is performed outside, by a linking component. This in turn, is called dependency injection. A typical IoC/DI framework allows you to write code that specifies a particular implementation of an interface that another component depends on, then allows you to instantiate that component and upon creation, the required implementation will be provided by the IoC container. This then abstracts the concept of object creation.

eulerfx
+1  A: 

Your questions warrant a fully fledged Wikipedia article. I assume you've already read up on the actual article so here's my shorter take on your question: Dependency Injection is all about instantiation.

The main idea is that classes should not be responsible for instantiating their dependencies. The DI framework takes over instantiation because it can do it flexibly, via a configuration mechanism that is (typically) external to your code.

This enables you to write classes that are:

  1. Decoupled from their dependencies.
  2. Better focused on their actual responsibility (rather than on their dependencies)
  3. Can be changed through configuration without the need for recompilation.
  4. More easily testable.
  5. Arguably, better designed.

To answer your second question: if you're trying to learn about DI then writing a framework yourself is clearly overkill. I would recommend that you choose one of the popular open source frameworks and write code that consumes it - most have good tutorials just for that purpose.

Taking it to the next level you can take the source code of the framework you were using and start digging into it. The good framework are very well written and relatively easy to read.

Good Luck! urig

PS - If you're in .net, don't start with MEF. Start with Windsor, Unity or Spring.Net. MEF is both more and less than a DI framework so leave it for a little later.

urig
+2  A: 

My very quick and dirty take on it

  • Dependency Injection and Inversion of Control are not the same thing. Inversion of Control uses DI.

  • IoC is a way of snapping your application together at run time rather than compile time.

  • Instead of 'newing up' a type in the code, it is injected at run time by the IoC container.

  • The IoC container knows what to inject into your class because a) It looks at the constructor of that class - all the parameters are interfaces. b) It looks at its configuration file and sees what classes that implement each interface you have chosen to represent that interface in your application.

Here's a very basic example

Let's say you have an interface IEmailer for sending emails:

public interface IEmailer
{
    void SendEmail();
}

And you have at least one implementation of this interface:

public class IainsEmailer : IEmailer
{
    public void SendEmail()
    {
        // Send email
    }
}

You define in IoC container's config file (somehow):

IainsEmailer is my choice for IEmailer

Then in your code you can have the following and the IoC container will inject an IainsEmailer into any constructor that needs an IEmailer.

public class MyClass
{
    private IEmailer _emailer;

    public MyClass(IEmailer emailer)
    {
        _emailer = emailer
    }

    // You can now use emailer as if you have created it
    _emailer.SendEmail();
}

I could go on. And on. But this really is the whole idea of IoC in a nutshell.

IainMH