Instead of having your objects create a dependency or ask a factory object to make one for them, you pass the needed dependencies in to the object externally, and you make it somebody else's problem. This "someone" is a dependency injector that builds the dependency graph.
Dependency Injection is a technique whereby one object supplies the dependencies of another object.
Suppose you want to inject an instance of a service class to your controller class in Java, you can do it by autowiring it:-
@Autowired
UserService userService;
I am new to Angular JS, so you can find the working of DI in Angular JS here.
There are different types of dependency injection the trivial implementation is a registry pattern aka. service-locator / service provider where for example you define certain keys and you can access them via get
registry.set('service-name', (param) => { return new Service(param); });
let bla = registry.get('service-name');
this helps you to have one place to reuse certain parts and replace them for mocking purposes;
because in your application you just take whatever is inside that registry and if the interface is the same you can access it.
that's the "service locator"/"registry-pattern" simply put .
there are multiple ways to implement such a thing for example using virtual variable names with a generic getter / setter / decorators. Decorators in ES6 / ES7 are the way to go i think.
@httpClient
class myClass {
constructor(){
this.httpClient.request('get','www.example.com');
}
}
The real DI is more complex and usually does not need an existing instance as the service pattern does. you just tell it what you need and annotate / decorate it
@DI('classname', options....)
@DI(MyClass myClass, param1, param2)
public void myFancyMethod(Classname class, MyClass myClass) {}
in the DI you can define multiple behaviours so for example you could use defined meta abstractions like yml files or xml to define building plans for those instances
or since in java all objects are on the heap you could use references from inside the framework.
The idea opposing to the service-locator is that the DI is more declarative. you just say what you want and where you want it. You don't pass an reference and resolve it with some deferred references.
tbh. I don't know how they implemented it in Angular :) but that's a rough concept of it.
Thanks of replying i am trying to understand dependency injection.Later let you know whether i have cleared about the D.I. or not.
Mev-Rael
Executive Product Leader & Mentor for High-End Influencers and Brands @ mevrael.com
Imagine your app uses an ajax library. (axios or Api). I will provide an example with Api since I am an author. It's a 3rd party code and in normal languages (not JavaScript) you can not change it and usually it source is located under vendor/node_modules or similar directory which is in gitignore.
You probably are not using this library directly, but it is used by many of your application models/controllers/ORMs/whatever. So you have a simple dependency.
You want to change the behavior of how a 3rd party code works in your App, for example what would happen if 404 occurs (ajax request URL failed). The only way you can achieve it "extending" a parent class/library. For example you created a new Core or Services folder in your app and put there MyApi. However, all your models/controllers/ORMs/etc still uses Api and not MyApi, you, of course, may do a global project find-and-replace, but it is not a secure and maintainable solution. So what if instead of that we could just make change in 1 part of our app and to tell our app that whenever we want to do ajax call we want to use MyApi and not Api? This is basically what Dependency Injection (DI) in simple words is.
In normal languages (not JavaScript) you will have to make a register for your dependencies, it's like a simple map (assoc array) where key is dependency name and value is component/object/class/function associated with that key, so whenever you would like to make ajax call you will need first get dependency from this register which is usually called Container and code may look like this:
// add (override/rebind) dependency to container Container.bind('Api', MyApi); // later in any part of your app you may access MyApi via const Api = Container.get('Api');However let me tell you that DI in JavaScript is very easy. First of all I would not recommend using Angular since it is very overcomplicated and worst architecture for web I ever seen. Second, JavaScript is very simple language where everything is accessible from everywhere, you can remove almost anything on window object or change native prototypes. There is no need of containers in JavaScript, I am just "binding" to window:
window.Api = MyApi; // that's all! only 1 line and everywhere in my app // whenever I call Api I will access MyApi // since all global calls in JS are bound to window object.And I will tell you more, since ES6 and imports/exports it become even better! Put your "dependencies" in Core folder for example even if you are not going to "inject" (replace) 3rd party code with your extended object and later just import that file and not directly 3rd party code, for example:
// core/Api.js: export { Api } from 'bunnyjs/src/Api'; // in the future if I will need to change something, // I will do it here// All other files just do this import { Api } from 'core/Api'; // and NOT this import { Api } from 'bunnyjs/src/Api';