This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

What is the

When it comes to back-end frameworks, the terms often heard are dependency injection and inversion of control, two concepts popularized by Java that have become a best practice for back-end frameworks. So what are dependency injection and inversion of control?

Dependency injection and inversion of control are different versions of the same concept.

Dependency injection means that the dependencies between components are determined by the container at runtime. The containers here can often be thought of as running frameworks such as Spring, Midway, etc. That is, dependencies between components are injected by the container at run time.

Inversion of Control means that the dependent content of the component is not brought into the object but is handed to the container for control (inversion).

As you can see, dependency injection emphasizes the concept of the body of the container; Inversion of control emphasizes the transfer of dependent control (from within components to containers).

why

Dependency injection and inversion of control are ideas that reduce the high coupling between components and make the entire application architecture more flexible. Let us do not need to care about where the resources come from, by who to achieve, just through simple configuration, can specify the target needs of the resources, improve the flexibility and scalability of the system.

implementation

The following implements a simple dependency injection container. A brief introduction to the implementation principle.

  1. To initialize the container, execute init, retrieve the file, and store the class and its contents in a mapping table
  2. When you run it, you use a class, you call get, you look it up in the cache, you return it
  3. The cache does not. Add the class to the cache and recurse on its dependencies
const globby = require('globby');
const path = require('path');

class Container {

  cwd = process.cwd();
  cache = {};
  classTable = {};

  init() {
    const fileResults = globby.sync(['**/**.ts'.'**/**.js'] and {cwd: this.cwd,
      ignore: [
        '**/node_modules/**',]});for (const name of fileResults) {
      const exports = require(this.cwd + '/' + name);
      this.classTable[this.getName(exports)] = exports; }}getName(Module) {
    return Module.name.toLowerCase();
  }

  get(Module) {
    if(this.cache[this.getName(Module)]) {
      return this.cache[this.getName(Module)];
    }

    const obj = new Module();
    this.cache[this.getName(Module)] = obj;
    const properties = Object.getOwnPropertyNames(obj);
    for(let p of properties) {
      if(! obj[p]) {if(this.classTable[p]) {
          obj[p] = this.get(this.classTable[p]);
        }
      }
    }
  }
}

const container = new Container();
const a = container.get(A);
Copy the code

reference

  • Segmentfault.com/a/119000000…
  • Mp.weixin.qq.com/s/g07BByYS6…
  • www.midwayjs.org/docs/contai…