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

NodeJS in Spring style with InversifyJS

By Mathieu Breton

NodeJS in Spring style with InversifyJS

This presentation demonstrates how we are able to develop like in Spring (the famous Java Framework) in a NodeJS Application.

  • 1,957