Angular2 DI in Typescript. Can we use it in node.js / non-angular projects?

前端 未结 6 889
孤独总比滥情好
孤独总比滥情好 2020-12-05 13:41

Was the angular2 dependency injection container designed for standalone use, and is it possible to use it for typescript/javascript server-side applications ?

I open

相关标签:
6条回答
  • 2020-12-05 14:05

    At the moment the Angular 2.0 DI code doesn't seem to be ready to be consumed by other libraries.

    I would like to suggest an alternative. I have developed an IoC container called InversifyJS with advanced dependency injection features like contextual bindings. It works in both node and browsers and some parts of its API are based on the Angular 2 DI API.

    You need to follow 3 basic steps to use it:

    1. Add annotations

    The annotation API is based on Angular 2.0:

    import { injectable, inject } from "inversify";
    
    @injectable()
    class Katana implements IKatana {
        public hit() {
            return "cut!";
        }
    }
    
    @injectable()
    class Shuriken implements IShuriken {
        public throw() {
            return "hit!";
        }
    }
    
    @injectable()
    class Ninja implements INinja {
    
        private _katana: IKatana;
        private _shuriken: IShuriken;
    
        public constructor(
            @inject("IKatana") katana: IKatana,
            @inject("IShuriken") shuriken: IShuriken
        ) {
            this._katana = katana;
            this._shuriken = shuriken;
        }
    
        public fight() { return this._katana.hit(); };
        public sneak() { return this._shuriken.throw(); };
    
    }
    

    2. Declare bindings

    The binding API is based on Ninject:

    import { Kernel } from "inversify";
    
    import { Ninja } from "./entities/ninja";
    import { Katana } from "./entities/katana";
    import { Shuriken} from "./entities/shuriken";
    
    var kernel = new Kernel();
    kernel.bind<INinja>("INinja").to(Ninja);
    kernel.bind<IKatana>("IKatana").to(Katana);
    kernel.bind<IShuriken>("IShuriken").to(Shuriken);
    
    export default kernel;
    

    3. Resolve dependencies

    The resolution API is based on Ninject:

    import kernel = from "./inversify.config";
    
    var ninja = kernel.get<INinja>("INinja");
    
    expect(ninja.fight()).eql("cut!"); // true
    expect(ninja.sneak()).eql("hit!"); // true
    

    The latest release (2.0.0) supports many use cases:

    • Universal JavaScript (Works in Node.js and Browsers)
    • Kernel modules
    • Kernel middleware
    • Use classes, string literals or Symbols as dependency identifiers
    • Injection of constant values
    • Injection of class constructors
    • Injection of factories
    • Auto factory
    • Injection of providers (async factory)
    • Activation handlers (used to inject proxies)
    • Multi injections
    • Tagged bindings
    • Custom tag decorators
    • Named bindings
    • Contextual bindings
    • Friendly exceptions (e.g. Circular dependencies)

    You can learn more about it at https://github.com/inversify/InversifyJS

    0 讨论(0)
  • 2020-12-05 14:08

    Seems someone has extracted dependency injection from Angular2 recently(Jan 2017), which allow it to use outside of the framework.

    https://github.com/mgechev/injection-js

    0 讨论(0)
  • 2020-12-05 14:09

    Checkout ubiquits sources - he did somehow integrated angular 2's DI on the backend.

    If you want simple but powerfull and painless dependency injection tool for typescript and node.js typedi. It works great with angular frontends too. Also checkout other repositories of this author, there are lot of components that will help you to build node applications using TypeScript.

    0 讨论(0)
  • 2020-12-05 14:16

    I doubt it, it doesn't look like it has been extracted into a component. It's a bit sad that major frameworks like Angular still have this monolithic approach, I would rather like to see Component oriented frameworks like Symfony, but JavaScript isn't quite there yet.

    In the meantime you have InversifyJS that doesn't look bad.

    0 讨论(0)
  • 2020-12-05 14:20

    As of Angular 2 RC.5, DI is a part of @angular/core package. For non-Angular uses, it was recently extracted into injection-js package by Minko Gechev, a member of Angular team.

    Here is a short ES6, Node-friendly example:

    // may not be needed for injection-js and recent @angular/core versions
    // if ES5-flavoured `Class` helper isn't used
    require('reflect-metadata');
    
    const { Inject, Injector, ReflectiveInjector, OpaqueToken } = require('@angular/core');
    // or ... = require('injection-js');
    
    const bread = new OpaqueToken;
    const cutlet = new OpaqueToken;
    
    class Sandwich {
        constructor(bread, cutlet, injector) {
            const anotherBread = injector.get('bread');
    
            injector === rootInjector;
            bread === 'bread';
            anotherBread === 'bread';
            cutlet === 'cutlet';
        }
    }
    
    Sandwich.parameters = [
        new Inject(bread),
        new Inject(cutlet),
        new Inject(Injector)
    ];
    
    const rootInjector = ReflectiveInjector.resolveAndCreate([
        { provide: 'bread', useValue: 'bread' },
        { provide: bread, useValue: 'bread' },
        { provide: cutlet, useValue: 'cutlet' },
        Sandwich
    ]);
    
    const sandwich = rootInjector.get(Sandwich);
    
    0 讨论(0)
  • 2020-12-05 14:29

    There is an awesome port of the Angular DI: https://github.com/mgechev/injection-js

    0 讨论(0)
提交回复
热议问题