开发者

Is fetching an object from a container and example of dependency injection?

Is the example below Dependency Injection with regard to the Worker class? The Worker class isn't obtaining the ITool instance from a property setter or constructor, but is rather fetching it from a container?

public MainClass {

    static void Main(string[] args) {
        ITool someTool = new Tool();
        MyContainer.Register<ITool>(someTool);
    }
}

public class MyContainer {

    private WindsorContainer container;

    public MyContainer() {
        container = new WindsorContainer();
    }

    public static T Resolve<T>() {
        return container.Resolve<T>();
    }

    public static void Register<T>(object instance) {
        container.Kernel.AddComponentInstance(typeof(T).ToString(), typeof(T), instance);
    }
}

public class Worker {

    public DoSomeWork() {
        ITool tool = MyContai开发者_C百科ner.Resolve<ITool>();
        tool.DoTheWork();
    } 
}


For me it's an example of Inversion of Control, and the Dependency Inversion Princial, as the Worker class is requesting the ITool from the container, rather than instantiating it itself, but it's not really an example of Dependency Injection as the dependency isn't "injected" from externally, it's "requested" from internally.

The terms can be quite confusing, and are often used interchangeably (incorrectly), however as long as your code is decoupled so you're not reliant on concrete implementations or "new-ing" things up in your "modules" then you are gaining the core advantages.

Personally it's very rare that I don't do constructor injection, even if I'm not using an overarching container - I find it the easiest method for unit tests etc.


What you have here is "Service Location" rather than "Dependency Injection", although both are examples of "Inversion of Control".

You'll want to read "Inversion of Control Containers and the Dependency Injection pattern", and pay close attention to this section.

Don't worry if you feel overwhelmed, it's a lot to take in all at once. For a slightly more structured introduction to a real world dependency injection tool, I highly recommend the Ninject User Guide.


Well, I guess it's not strictly 'injecting' the dependency. Worker still has a hard-coded dependency on MyContainer - I guess 'true' dependency injection would involve passing an ITool to Worker, instead of Worker looking up ITool.


IoC with containers is not as useful as dependency injection.

If you're not passing it in, you're not getting the advantages very much of anything. You're still heavily relying on a singleton-style global: your container object. Once you inject (pass) in the container object, you aren't gaining any benefit from the container! And, you also end up passing in an object that can resolve all kinds of global objects that you don't need! So why do it? It adds unneeded complexity. Containers and registries are good examples of astronaut ways of thinking.

Pass in exactly what you need, and only what you need. If you need something that implements ITool, pass it in. Don't forget to hint the passed in object as the ITool interface. That's all you need.


In addition to everything in Steven Robbins's answer, this is also an example of the Service Locator pattern, since the MyContainer class is acting like a Registy inside the Worker class


DI is often misunderstood. Here is a very simple example what DI is, http://codingcraft.wordpress.com/2011/06/23/dependency-injection-simplified/

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜