在Aurelia辅助注射?

Neo*_*aul 14 javascript dependency-injection aurelia

我有一个类,其构造函数有两个参数; 一个是依赖项,另一个是配置属性:

@inject(Dependency)
class MyClass{
  constructor(dependency, config){
  }
}
Run Code Online (Sandbox Code Playgroud)

如何利用Aurelia的依赖注入来自动注入依赖项,但允许类的使用者指定配置值?

Jer*_*yow 18

以下是一些选项:


选项0:工厂解析器

foo.js

import {inject} from 'aurelia-framework';
import {FooDependency} from './foo-dependency';

@inject(FooDependency)
export class Foo {
  constructor(dep, config) {
  }
}
Run Code Online (Sandbox Code Playgroud)

需求-foo.js

import {inject, Factory} from 'aurelia-framework';
import {Foo} from './foo';

@inject(Factory.of(Foo))
export class NeedsFoo {
  constructor(fooFactory) {
    let config = {};
    this.foo = fooFactory(config);
  }
}
Run Code Online (Sandbox Code Playgroud)

选项1:工厂

foo.js

import {inject} from 'aurelia-framework';
import {FooDependency} from './foo-dependency';

class Foo {
  constructor(dep, config) {
  }
}

@inject(FooDependency)
export class FooFactory {
  constructor(dep) {
    this.dep = dep;
  }

  makeFoo(config) {
    return new Foo(this.dep, config);
  }
}
Run Code Online (Sandbox Code Playgroud)

需求-foo.js

import {inject} from 'aurelia-framework';
import {FooFactory} from './foo';

@inject(FooFactory)
export class NeedsFoo {
  constructor(fooFactory) {
    let config = {};
    this.foo = fooFactory.makeFoo(config);
  }
}
Run Code Online (Sandbox Code Playgroud)

选项2:儿童容器

foo.js

import {inject} from 'aurelia-framework';
import {FooDependency} from './foo-dependency';

export const configKey = 'config';

@inject(FooDependency, configKey)
export class Foo {
  constructor(dep, config) {
  }
}
Run Code Online (Sandbox Code Playgroud)

需求-foo.js

import {inject, Container} from 'aurelia-framework';
import {Foo, configKey} from './foo';

@inject(Container)
export class NeedsFoo {
  constructor(container) {
    let config = {};
    let childContainer = container.createChild();
    childContainer.registerInstance(configKey, config);
    this.foo = childContainer.get(Foo);
  }
}
Run Code Online (Sandbox Code Playgroud)

选项3:蛮力

foo.js

export class Foo {
  constructor(dep, config) {
  }
}
Run Code Online (Sandbox Code Playgroud)

需求-foo.js

import {inject, Container} from 'aurelia-framework';
import {FooDependency} from './foo-dependency';
import {Foo} from './foo';

@inject(Container)
export class NeedsFoo {
  constructor(container) {
    let config = {};
    let dep = container.get(FooDependency);
    this.foo = new Foo(dep, config);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 啊,非常好,应该放在aurelia docs的某个地方 (3认同)

Neo*_*aul 2

最后,我创建了一个自定义解析器,这意味着代码很好且模块化,并且易于在其他类中使用。

foo.js

import {inject} from 'aurelia-framework';
import {FooDependency} from './foo-dependency';

@inject(Dependency)
export class Foo{
  constructor(dep, cfg){}

  static useArgs(...args){
     return new Resolver(Foo, args);
  }
}

@resolver
class Resolver{
  constructor(Class, args){
    this.Class = Class;
    this.args = args;
  }

  get(container){
    var Class = this.Class,
      // Class.inject is the array of the class's dependencies
      // we need to resolve them all before they're useful
      dependencies = Class.inject.map((dep)=>container.get(dep)),
      // Pass the resolved dependencies + any additional arguments to the new class
      args = dependencies.concat(this.args);

    return new Class(...args);
  }
}
Run Code Online (Sandbox Code Playgroud)

需求-foo.js

import {inject} from 'aurelia-framework';
import {Foo} from 'foo';

@inject(Foo.useArgs('my config'))
export class NeedsFoo{
    constructor(fooConfigured){
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 天啊-我以为你需要在每次实例化“Foo”时动态设置配置。看起来对于您的需求,我们所做的一切都不需要。您需要做的就是在容器中注册您的配置:`container.registerInstance('config key', myConfig);`,然后将`@inject(Dependency, 'config key')`添加到`Foo`。 (3认同)