views:

186

answers:

4

Hi, I've been reading about Inversion of Control frameworks and I'm just playing around with the question: "Why in the hell do I need a framework to do this?"

Don't misunderstood my question... the pattern is something we programmers use often but... a full featured framework to do that?

I must be missing something and that's the reason I'm posting the question. I've seen a lot of examples on the web and I just don't get it. mi mind is blocked to the idea maybe.

Just take a look at the Ninject Home page's example:

public class Samurai {
    public IWeapon Weapon { get; private set; }
    public Samurai(IWeapon weapon) {
        Weapon = weapon;
    }
}

public class WarriorModule : NinjectModule {
    public override void Load() {
        Bind< IWeapon >.To< Sword >();
    }
}

The "Samurai" class is ok to me. The "NinjectModule" framework seems unnecessary to me.

I'm assuming later in the code we will be creating new "Samurai" instances passing in "Sword" instances to it, something like:

Samurai theWarrior = new Samurai(WarriorModule.GetInstance(IWeapon));//no coupling

which could be replaced by:

Samurai theWarrior = new Samurai(new Sword());//still no coupling

or

Samurai theWarrior = new Samurai(GetWeaponFromXML());//no coupling yet

What's the part I'm missing? Could you please tell of some scenario where Ioc framework could be needed in my Application?

Thanks.

UPDATE AFTER 4 ANSWERS: I really liked all of the answers I got from you guys. I just read this post dependency-injection-dissection/ where the guy use it for Unit Testing and the StackOverflow link you just provided and Yeah, I was missing the big-big-big complexity part, so let custom myself to use a IoC framework. Thanks again.

I would vote your answers but I just get an orange message saying I can't.

Thanks to the guy who highlighted the code I posted.

+3  A: 

This is the problem with code samples. They're either complex and you haven't explained your point, or they're trivial and then seem pointless.

What the WarriorModule is doing is binding a concrete type to an interface, and so whenever another class needs an implementation of that interface, it receives one automatically by the IoC container. The class with the dependency has no dependency on the concrete type, and so has lower coupling and higher testability. I think you knew that already.

In your replacement scenarios, the Samurai class isn't coupled to the sword class, but the calling code still is. You could push that out another level, but that code would now have the dependency, and your intervening class would now have to marshall all the dependencies.

The IoC container does this for all mappings, putting it in only a few places (the module classes). The rest of your code is free not to care, not to have dependencies on concrete types.

Hope that helps.

dpurrington
+1  A: 

I recently started using the Unity for IoC and have no doubt it makes my life easier.

I'll just paste in my code verbatim and hope you find it useful. Someone more experienced might give you more.

Also, I found it useful to read the paper about DI by Fowler.

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        using (IUnityContainer container = new UnityContainer())
        {
            container

                .RegisterType<ILogger, StatSyncherFormView>(new myLife())

                // GUI
                .RegisterType<IStatSyncherView, StatSyncherFormView>()

                // Services
                .RegisterType<ISalesForceWebServices, SalesForceWebServices1>()

                .RegisterInstance(new SalesForceWebServices1(
                    "XXX", "XXX",
                   "https://login.salesforce.com/services/Soap/c/19.0/0DF70000000CfHq",
                    "https://na5-api.salesforce.com/services/Soap/s/19.0"))


                .RegisterType<ISalesForceService, SalesForceService1>()

                .RegisterType<IRestApiCall, RestApiCall1>()

                .RegisterType<IDirectTrackService, DirectTrackService1>()

                .RegisterType<IDAgentsService, DAgentsService1>()

                .RegisterType<IQuickBooksService, QuickBooksService1>();

            StatSyncherPresenter p = container.Resolve<StatSyncherPresenter>();

            Application.Run((Form)p.view);
        }
    }

One of the things I find most useful is:

public class AnyClassCreatedByContainer
{
    [Dependency]
    public ILogger Logger { get; set; }
}
Gabriel
+1  A: 

Although Samurai theWarrior = new Samurai(new Sword()); is still no coupling, if you would want to give all samurais in your application a <insert favourite weapon here>, you would have to change all your calling code to change to the new weapon, whereas with IoC you would change it in one spot and all your samurais would be using the new weapon.

Jappie
+3  A: 

Your example is pretty straight forward having just the two layers, but when you have a real life example it soon gets messy:

var form = new OrderEntryForm(
    new OrderService(
        new OrderReposity(
            new DatabaseGateway(
                new DataProviderFactory()))))

An IoC container can do all the wiring up for you, making your life a lot easier.

This is an example from a similar question, which goes in to all the details: http://stackoverflow.com/questions/45191/ioc-explain-and-more-important-when-to-use-it/45197#45197

Iain Hoult