167

First, I would like to separate the design approach from the concept of frameworks. Dependency injection at its simplest and most fundamental level is simply: A parent object provides all the dependencies required to the child object. That's it. Note, that nothing in that requires interfaces, frameworks, any style of injection, etc. To be fair I first ...


126

When the object itself is responsible for requesting its dependencies, as opposed to accepting them through a constructor, it's hiding some essential information. It's only mildly better than the very tightly-coupled case of using new to instantiate its dependencies. It reduces coupling because you can in fact change the dependencies it gets, but it still ...


124

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. This is the essence of the Dependency Inversion Principle: "a dependency should never be ...


105

Well yes, you inject your dependencies, either through a constructor or through properties. One of the reasons for this, is not to encumber MyClass with the details of how an instance of MyInterface needs to be constructed. MyInterface could be something that has a whole list of dependencies by itself and the code of MyClass would become ugly very fast if ...


104

Now, to build a simple file saving application you have a class to check if the file already exists, a class to write the metadata, a class to abstract away DateTime.Now so you can inject times for unit testing, interfaces for every file containing logic, files to contain unit tests for each class out there, and one or more files to add everything to your DI ...


99

I'm no expert, but I think I can help. And yes, it's a specific type of Dependency Injection. Disclaimer: Almost all of this was "stolen" from the Ninject Wiki Let’s examine the idea of dependency injection by walking through a simple example. Let’s say you’re writing the next blockbuster game, where noble warriors do battle for great glory. First, we’ll ...


90

Dependency injection is, like most patterns, a solution to problems. So start by asking if you even have the problem in the first place. If not, then using the pattern most likely will make the code worse. Consider first if you can reduce or eliminate dependencies. All other things being equal, we want each component in a system to have as few dependencies ...


88

In many cartoons or other media, the forces of good and evil are often illustrated by an angel and a demon sitting on the character's shoulders. In our story here, instead of good and evil, we have SOLID on one shoulder, and YAGNI (You ain't gonna need it!) sitting on the other. SOLID principles taken to the max are best suited for huge, complex, ultra-...


79

Imagine you are a worker in a factory that makes shoes. You are responsible for assembling the shoes and so you'll need a lot of things in order to do that. Leather Measuring tape Glue Nails Hammer Scissors Shoe laces And so on. You're at work in the factory and you're ready to start. You have list of instructions on how to proceed, but you don't have ...


74

Use dependency injection, but whenever your constructor argument lists become too big, refactor it using a Facade Service. The idea is to group some of the constructor arguments together, introducing a new abstraction. For example, you could introduce a new type SessionEnvironment encapsulating a DBSessionProvider, the UserSession and the loaded ...


62

Taking a couple of the counter arguments: "We want to keep it simple, if possible just stuff everything into one assembly. DI is an uneeded complexity with no benefit". "its not like we will be plugging in different implementations of components". What you want is for the system to be testable. To be easily testable you need to be looking at mocking ...


56

From what you are writing, not DI itself is taboo, but the use of DI containers, which is a different thing. I guess you will get no problems with your team when you just write independent components which get other components they need passed, for example, by the constructor. Just don't call it "DI". You may think for such components not to use a DI ...


52

How DI can be implemented depends very much on the language used. Here is a simple non-DI example: class Foo { private Bar bar; private Qux qux; public Foo() { bar = new Bar(); qux = new Qux(); } } This sucks, e.g. when for a test I want to use a mock object for bar. So we can make this more flexible and allow instances to ...


51

Since you asked, I'll take the side of your team against DI. The case against Dependency Injection There is a rule I call "Conservation of Complexity" that is analogous to the rule in physics called "Conservation of Energy." It states that no amount of engineering can reduce the total complexity of an optimal solution to a problem, all it can do is shift ...


49

This is not a God object. It seems like it is because there is so much here, but, in a way, it's doing nothing at all. There is no behavior code here. This isn't an omnipotent God that does everything. It just finds everything. It's less a true object at all and more of a data structure. This pattern has a more proper name: Service Locator. It strongly ...


48

Our friends on Stack Overflow have a nice answer to this. My favourite is the second answer, including the quote: "Dependency Injection" is a 25-dollar term for a 5-cent concept. (...) Dependency injection means giving an object its instance variables. (...). from James Shore's blog. Of course, there are more complex versions / patterns layered on top of ...


48

Field injection is a bit too "spooky action at a distance" for my taste. Consider the example you provided in your Google Groups post: public class VeracodeServiceImplTest { @Tested(fullyInitialized=true) VeracodeServiceImpl veracodeService; @Tested(fullyInitialized=true, availableDuringSetup=true) VeracodeRepositoryImpl veracodeRepository;...


44

As always, It Depends™. The answer depends on the problem one is trying to solve. In this answer, I'll try to address some common motivating forces: Favour smaller code bases If you have 4,000 lines of Spring configuration code, I suppose that the code base has thousands of classes. It's hardly an issue that you can address after the fact, but as a rule ...


43

So, what am I missing? Dependency Injection decreases coupling between a class and its dependency. But it increases the coupling between a class and its consumer (since the consumer needs more info to create it) and the dependency and its consumer (since the consumer needs to know the dependency to use). Very often, this is a good trade off. The class ...


41

No. SOLID exists as guidelines to account for inevitable change. Are you really never going to change your logging library, or target, or filtering, or formatting, or...? Are you really not going to change your caching library, or target, or strategy, or scoping, or...? Of course you are. At the very least, you're going to want to mock these things in a ...


39

There are plenty of reasons why non-mutable globals are evil in OOP. That is a dubious claim. The link you use as evidence refers to state - mutable globals. They are decidedly evil. Read only globals are just constants. Constants are relatively sane. I mean, you're not going to inject the value of pi into all your classes, will you? If the number or ...


39

Yes This is the whole point of the term "cross-cutting concern" - it means something that does not fit neatly in the SOLID principle. This is where idealism meets up with reality. People semi-new to SOLID and cross-cutting often run into this mental challenge. It's OK, don't freak out. Strive to put everything into terms of SOLID, but there are a few ...


38

Cross-cutting Concerns like logging, caching etc. are not dependencies, so shouldn't be injected into services. However, while most people then seem to reach for a full interleaving AOP framework, there's a nice design pattern for this: Decorator. In the above example, let MyService implement the IMyService interface: public interface IMyService { void ...


37

in the case where almost everyone needs to know about a certain data structure, why is Dependency Injection any better than a global object? Dependency injection is the best thing since sliced bread, while global objects have been known for decades to be the source of all evil, so this is a rather interesting question. The point of dependency injection is ...


36

In my experience, there are a number of downsides to dependency injection. First, using DI does not simplify automated testing as much as advertised. Unit testing a class with a mock implementation of an interface lets you validate how that class will interact with the interface. That is, it lets you unit test how the class under test uses the contract ...


30

Outside of dependency-injection frameworks, dependency injection (via constructor injection or setter injection) is very nearly a zero-sum game: you decrease the coupling between object A and it's dependency B, but now any object that needs an instance of A must now also construct object B. You've slightly reduced the coupling between A and B, but reduced A'...


30

Don't think yet about the tool that you are going to use. You can do DI without an IoC Container. First point: Mark Seemann has a very good book about DI in .Net Second: composition root. Make sure that the whole set up is done on the entry point of the project. Rest of your code should know about injections, not about any tool that is being used. Third:...


30

No. Tight coupling is much more than what dependency injection deals with. Dependency injection externalizes a decision of implementation. This goes a long way to decouple but coupling is more than just this. A good antonym for dependency injection is hard coding a dependency. When you construct (use new or directly use some factory) inside a behavior ...


30

Tasks that used to take 5-10 files can now take 70-100! This is the opposite of the single-responsibility principle (SRP). To get to that point, you must have divided up your functionality in a very fine-grained way, but that's not what the SRP is about -- doing that ignores the key idea of cohesiveness. According to the SRP, software should be divided ...


28

The argument of less test initialization boiletplate is valid, but there are other concerns that must be taken into account. First of all, you have to answer a question: Do I want my class to be instantiable only with reflection? Using field injections means narrowing down compatibility of a class to dependency injection environments that instantiate ...


Only top voted, non community-wiki answers of a minimum length are eligible