Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there ever a case for 'new' when using dependency injection?

Does dependency injection mean that you don't ever need the 'new' keyword? Or is it reasonable to directly create simple leaf classes such as collections?

In the example below I inject the comparator, query and dao, but the SortedSet is directly instantiated:

public Iterable<Employee> getRecentHires()
{
    SortedSet<Employee> entries = new TreeSet<Employee>(comparator);
    entries.addAll(employeeDao.findAll(query));
    return entries;
}
like image 893
parkr Avatar asked Feb 10 '09 02:02

parkr


People also ask

Does dependency injection create a new instance?

If you inject a dependency into your class the container provides you a new instance for this specific dependency.

Why we should not use dependency injection?

Basically, dependency injection makes some (usually but not always valid) assumptions about the nature of your objects. If those are wrong, DI may not be the best solution: First, most basically, DI assumes that tight coupling of object implementations is ALWAYS bad.

What problems does dependency injection solve?

Dependency injection supports these goals by decoupling the creation of the usage of an object. That enables you to replace dependencies without changing the class that uses them. It also reduces the risk that you have to change a class just because one of its dependencies changed.

Which is the major limitation of dependency injection?

Disadvantages of Dependency Injection: Dependency injection creates clients that demand configuration details to be supplied by construction code. This can be difficult when obvious defaults are available. Dependency injection can make code difficult to trace (read) because it separates behaviour from construction.


2 Answers

Just because Dependency Injection is a useful pattern doesn't mean that we use it for everything. Even when using DI, there will often be a need for new. Don't delete new just yet.

like image 83
Don Branson Avatar answered Oct 15 '22 18:10

Don Branson


One way I typically decide whether or not to use dependency injection is whether or not I need to mock or stub out the collaborating class when writing a unit test for the class under test. For instance, in your example you (correctly) are injecting the DAO because if you write a unit test for your class, you probably don't want any data to actually be written to the database. Or perhaps a collaborating class writes files to the filesystem or is dependent on an external resource. Or the behavior is unpredictable or difficult to account for in a unit test. In those cases it's best to inject those dependencies.

For collaborating classes like TreeSet, I normally would not inject those because there is usually no need to mock out simple classes like these.

One final note: when a field cannot be injected for whatever reason, but I still would like to mock it out in a test, I have found the Junit-addons PrivateAccessor class helpful to be able to switch the class's private field to a mock object created by EasyMock (or jMock or whatever other mocking framework you prefer).

like image 34
Jeff Olson Avatar answered Oct 15 '22 16:10

Jeff Olson