Fait moi rêver

  • DI, Ioc, Kamouloxx ?
     
  • Inversify
     
  • Demo

DependencY INJECTION

Aka : DI

DI : Why ?

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

DI : What ?

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);

DI : What ?

Easy to test :

describe('Class A', () => {
    it('should behaves as expected', ()=> {
        // given
        const mockOfB = {
            fakeMethod() {
                /* do something */
            }
        };
        const a = new A (mockOfB);
        
        // when -> then ...
    });
});

Injection of Control

Aka : IoC

Ioc : Why ?

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 : What ?

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

Ioc : Spring, The IOC Framework for Java

@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;
    }
}

So, IOC in JavaScript ?


InversifyJS

InversifyJS

A powerful and lightweight inversion of control container
for JavaScript & Node.js apps powered by TypeScript.

Powered by TypeScript ???

InversifyJS

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'

Demo

Phoenix-API

Conclusion

 

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

One more thing

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

Made with Slides.com