开发者

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

开发者 https://www.devze.com 2023-02-07 06:55 出处:网络
This question already has answers here: Closed 12 years ago. Possible Duplicate: Is it better to create a singleton to access unity container or pass it through the application?
This question already has answers here: Closed 12 years ago.

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(); 开发者_如何学Go}
}

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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号