Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IoC container - singleton or passed around instance? [duplicate]

Possible Duplicate:
Is it better to create a singleton to access unity container or pass it through the application?

I am introducing IoC container into the system. The natural question is, should it be a singleton or an instance passed to a class to use? I lean towards having it as a singleton instance because:

  1. No need to clutter class definition like constructors, additional properties.
  2. Clearer - one instance per application, one initialization routing.
  3. Ability to have default mapping with overrides if necessary (like for unit testing).

Here is how it looks:

class Main
{
  public static void main(params string[] args)
  {
     IoCContaner.Intance.Add<IBar>();
     IoCContaner.Intance.Add<IBaz>();
     IoCContaner.Intance.Add<IQux>();

     var foo = new Foo();
     Foo.DoBarStuff();
  }
}

class Bar : IBar 
{ 
  public Bar(IBaz, IQuz) {} 
  public void DoBazStuff() { _baz.DoStuff(); }
}

class Foo
{
  public void DoBarStuff()
  {
     var bar = IoCContaner.Intance.Resolve<IBar>();
     bar.DoBazStuff();
  }
}

Is there anything I am missing and instead I should actually have something like:

class Foo
{
  IoCContainer _c;
  public Foo(IoCContainer c) { _c = c; }
  ...
  private void DoBarStuff()
  {
     var bar = _c.Resolve<IBar>();
     bar.DoBazStuff();
  }
}

Of course with the second approach I may always to fall back to the first one by passing around a singleton container instance.

EDITED: updated code examples

like image 402
Schultz9999 Avatar asked Jan 27 '11 18:01

Schultz9999


1 Answers

Neither: both of those approaches hide your dependencies and make your classes hard to use. Instead, Foo should require an IBar in its constructor:

class Foo {
    private bar;
    public Foo(IBar bar) { this.bar = bar; }
    private void DoBarStuff() {
        this.bar.DoStuff();
    }
}

The only things that should know about your container are your application entry points.

See Dependency Injection Myth: Reference Passing and Service Locator is an Anti-Pattern for additional in-depth discussion.

like image 141
Jeff Sternal Avatar answered Sep 22 '22 10:09

Jeff Sternal