views:

79

answers:

4

Is there any layer where it is bad practice to use DI? In a previous question a user mentioned that DI should only be used in the UI layer.

+3  A: 

DI should be used in any case where one component is dependent on another, whether it's UI --> Business, Business --> Data Access or whatever. I don't think it should only be used for UI, it's just that DI makes testing the UI easier, and so appears to have more of an immediate benefit.

DaveDev
+2  A: 

I disagree with that statement. Either the previous question you cite is incorrect or you misinterpreted it.

DI is certainly not only in the UI layer. I would only agree with that on the condition that controllers are part of the view layer.

You use DI wherever dependencies can be properly provided.

Whether you choose to use a factory or a DI solution is your choice.

duffymo
+5  A: 

I think that you might be misinterpreting the answer provided by Daren Dimitrov. Unless I'm mistaken, the line that spawned this question is: "Also you shouldn't be creating a dependency with the DI framework in the business layers of the application."

I believe what he is saying is that all dependency information/mappings should be be created at the highest level of an application. That is not to say that dependencies will not be present throughout all tiers of your application, just that the lower levels are not responsible for setting up the mappings.

If my interpretation is correct then I agree with him - set up your dependency mappings at the surface of your application. If instead he is saying that you should never resolve a dependency in the lower layers then I would have to disagree.

Andrew Anderson
+3  A: 

Dependency Injection (DI) should be used everywhere. However, notice that DI is only a set of patterns - not a framework or a library. The best way to think about DI is that it is loosely coupled code enabled by Constructor Injection. You can write DI-friendly code all the way without ever referencing a DI Container or using the Service Locator anti-pattern.

The next question that comes to mind, then, is where should components be composed? This is probably what is meant by the original statement: only compose the application in the outermost layer - UI or (web) service interface. This is what I call the Composition Root. It keeps the rest of the code modularized and flexible.

At the Composition Root, you can use Poor Man's DI or a proper DI Container. I stronly suggest that you use a DI Container, but it's not required.

To illustrate what I mean by DI, here's an example:

public class Foo : IFoo
{
    private readonly IBar bar;

    public Foo(IBar bar)
    {
        if (bar == null)
        {
            throw new ArgumentNullException("bar");
        }

        this.bar = bar;
    }

    public IBaz Baz(ISnafu snafu)
    {
        return this.bar.Snafize(snafu).ToBaz();
    }
}

The IBaz implementation could be implemented in a completely seperate library from the one defining the Foo class. Furthermore, consumers higher in the stack need not know anything about Foo and IBar - they can just consume IFoo:

public class MyClass : ISomeInterface
{
    private readonly IFoo foo;

    public MyClass(IFoo foo)
    {
        if (foo == null)
        {
            throw new ArgumentNullException("foo");
        }

        this.foo = foo;
    }

    // ...
}

This provides the loose coupling that is the motivation for DI. Repeat as much as necessary.

Mark Seemann