Lets imagine two classes A and B. A is using B :
A
B
class A {
constructor (){
this.b = new B(SECRET_KEY);
}
}
No Factorisation
Untestable
Strongly coupled
Bad separation of concerns
The fifth of SOLID principles in OOP. Dependencies should be given.
class A {
constructor (private b:B){ }
}
A
B
C
import A from './A';
import B from './B';
const b = new B();
const a = new A(b);
// ...
const anotherService = new D(b);
Easy to test :
describe('Class A', () => {
it('should behaves as expected', ()=> {
// given
const mockOfB = {
fakeMethod() {
/* do something */
}
};
const a = new A (mockOfB);
// when -> then ...
});
});
DI, is good, but give the dependencies at all is boring !
import UserService from '../service/user-service';
import SlackService from '../service/slack/slack-service';
import TenKiloService from '../service/ten-kilo/ten-kilo';
import axios from 'axios';
import bluebird from 'bluebird';
const userService = new UserService(
new SlackService(axios),
new TenKiloService(axios),
bluebird
);
IOC is a design pattern, used to dissociate elements in OOP and give an elegant way to build these elements.
A
B
C
Lightweight container
Responsible of elements building & connect them
@Controller
class VetController {
private final VetRepository vets;
@Autowired
public VetController(VetRepository clinicService) {
this.vets = clinicService;
}
@RequestMapping(value = { "/vets.html" })
public String showVetList(Map<String, Object> model) {
Vets vets = new Vets();
vets.getVetList().addAll(this.vets.findAll());
model.put("vets", vets);
return "vets/vetList";
}
@RequestMapping(value = { "/vets.json", "/vets.xml" })
public @ResponseBody Vets showResourcesVetList() {
Vets vets = new Vets();
vets.getVetList().addAll(this.vets.findAll());
return vets;
}
}
A powerful and lightweight inversion of control container
for JavaScript & Node.js apps powered by TypeScript.
Powered by TypeScript ???
Why TypeScript ?
How a container know who depends of who ?
class A {
constructor (b) {
this.b = b;
}
}
'b' is just a parameter name. So, how to know to build it ?
someModule.controller('MyController', ['$scope', 'dep1', function($scope, dep1) {
...
$scope.aMethod = function() {
...
}
}]);
In AngularJS, the names was 'injection keys'
It's cool, but is it really useful in JavaScript ?
Mock a dependency is easy in NodeJS
DI why not, but IOC it's maybe too much
Spring & Spring MVC in Node.JS !
import { Dependencies, Controller, RequestMapping, RequestMethod } from 'nest.js';
@Controller({ path: 'users' })
@Dependencies([ UsersService ])
export class UsersController {
constructor(usersService) {
this.usersService = usersService;
}
@Get()
getAllUsers(req, res, next) {
this.usersService.getAllUsers().then(users => res.status(200).json(users));
}
@Get('/:id')
getUser(req, res, next) {
this.usersService.getUser(+req.params.id).then(user => res.status(200).json(user));
}
@Post()
addUser(req, res, next) {
this.usersService.addUser(req.body.user).then(msg => res.status(201).json(msg));
}
}
Thank you