前端框架Aurelia - 依赖注入Dependency Injection(一)
2017-03-22 10:04
316 查看
Let's say we have a
needs to load a
by ID from a web service. We wouldn't want to place all the details of our AJAX implementation inside our
Instead, we would want to factor that into a
that our
or any other class, can use when it needs to load a
Aurelia's dependency injection container lets you accomplish this by declaring that the
to have a
at creation time.
我们不想把Ajax请求写在CustomerEditScreen里面,我们把Ajax请求放在CustomerService里面,这样任何class都可以利用这个文件请求。Aurelia's
dependency injection container 通过在创建时候声明CustomerEditScreen需要
Typically,
you would use Decorators, an ES Next feature supported by both Babel and TypeScript. Here's what it looks like to declare that the
a
Notice
that we use the
and that the constructor signature matches the list of dependencies in the
This tells the DI that any time it wants to create an instance of
must first obtain an instance of
it can inject into
the constructor of
instantiation. You can have as many injected dependencies as you need. Simply ensure that the
and the constructor match one another.
我们用inject修饰符,构造函数匹配inject里面列出的依赖。注意,构造函数里面的依赖必须要一一对应inject修饰符里里面的。这个告诉DI,它任何时候想要创建CustomerEditScreen实例,必须首先获得CustomerService实例,这个要获得的实例可以在CustomerEditScreen实例化的时候被注入到CustomerEditScreen的构造函数中。
多个依赖的注入需要构造函数里面的依赖和inject里面的依赖一一对应。
If you are using TypeScript, you can take advantage of an experimental
feature of the language to have the TypeScript transpiler automatically provide Type information to Aurelia's DI. You can do this by configuring the TypeScript compiler with the
of your
If you do this, you don't need to duplicate the type information with
instead, as long as your constructor definition contains its paramaters' types, you can use Aurelia's
like this
如果用的是ts,那么只需要进行上述的配置就可以自动注入依赖。inject换成了autoinject。
Interestingly,
you don't need to use our
at all to get the above to work. The TypeScript compiler will emit the type metadata if any decorator
is added to the class. Aurelia can read this metadata regardless of what decorator triggers TypeScript to add it. We simply provide the
for consistency and clarity.
其实如果用ts,连autoinject都不需要添加,之所以添加,只是为了让代码更清晰。
If
you aren't using Babel's or TypeScript's decorator support (or don't want to), you can easily provide
using a simple static method or property on your class:
如果babel和ts都不用,那么就这样添加依赖。用一个inject静态方法。
因为我们class文件里面的方法都是public或者private,我们想要使用必须对class进行实例化,只有static可以直接使用,
所以需要注入依赖实例化后才能调用。
CustomerEditScreenthat
needs to load a
Customerentity
by ID from a web service. We wouldn't want to place all the details of our AJAX implementation inside our
CustomerEditScreenclass.
Instead, we would want to factor that into a
CustomerServiceclass
that our
CustomerEditScreen,
or any other class, can use when it needs to load a
Customer.
Aurelia's dependency injection container lets you accomplish this by declaring that the
CustomerEditScreenneeds
to have a
CustomerServiceinjected
at creation time.
我们不想把Ajax请求写在CustomerEditScreen里面,我们把Ajax请求放在CustomerService里面,这样任何class都可以利用这个文件请求。Aurelia's
dependency injection container 通过在创建时候声明CustomerEditScreen需要
CustomerService注入来帮你完成。
Typically,
you would use Decorators, an ES Next feature supported by both Babel and TypeScript. Here's what it looks like to declare that the
CustomerEditScreenneeds
a
CustomerService
用修饰符,ES6特性,Babel和TS都支持。下面是个demo。
import {CustomerService} from 'backend/customer-service'; import {inject} from 'aurelia-framework'; @inject(CustomerService) export class CustomerEditScreen { constructor(private customerService: CustomerService) { this.customer = null; } activate(params) { return this.customerService.getCustomerById(params.customerId) .then(customer => this.customer = customer); } }
Notice
that we use the
injectdecorator
and that the constructor signature matches the list of dependencies in the
injectdecorator.
This tells the DI that any time it wants to create an instance of
CustomerEditScreenit
must first obtain an instance of
CustomerServicewhich
it can inject into
the constructor of
CustomerEditScreenduring
instantiation. You can have as many injected dependencies as you need. Simply ensure that the
injectdecorator
and the constructor match one another.
我们用inject修饰符,构造函数匹配inject里面列出的依赖。注意,构造函数里面的依赖必须要一一对应inject修饰符里里面的。这个告诉DI,它任何时候想要创建CustomerEditScreen实例,必须首先获得CustomerService实例,这个要获得的实例可以在CustomerEditScreen实例化的时候被注入到CustomerEditScreen的构造函数中。
多个依赖的注入需要构造函数里面的依赖和inject里面的依赖一一对应。
import {CustomerService} from 'backend/customer-service'; import {CommonDialogs} from 'resources/dialogs/common-dialogs'; import {EventAggregator} from 'aurelia-event-aggregator'; import {inject} from 'aurelia-framework'; @inject(CustomerService, CommonDialogs, EventAggregator) export class CustomerEditScreen { constructor(private customerService: CustomerService, private dialogs: CommonDialogs, private ea: EventAggregator) { this.customer = null; } activate(params) { return this.customerService.getCustomerById(params.customerId) .then(customer => this.customer = customer) .then(customer => this.ea.publish('edit', customer)); } }
If you are using TypeScript, you can take advantage of an experimental
feature of the language to have the TypeScript transpiler automatically provide Type information to Aurelia's DI. You can do this by configuring the TypeScript compiler with the
"emitDecoratorMetadata": trueoption in the
compilerOptionssection
of your
tsconfig.jsonfile.
If you do this, you don't need to duplicate the type information with
inject,
instead, as long as your constructor definition contains its paramaters' types, you can use Aurelia's
autoinjectdecorator
like this
如果用的是ts,那么只需要进行上述的配置就可以自动注入依赖。inject换成了autoinject。
Interestingly,
you don't need to use our
autoinjectdecorator
at all to get the above to work. The TypeScript compiler will emit the type metadata if any decorator
is added to the class. Aurelia can read this metadata regardless of what decorator triggers TypeScript to add it. We simply provide the
autoinjectdecorator
for consistency and clarity.
其实如果用ts,连autoinject都不需要添加,之所以添加,只是为了让代码更清晰。
import {CustomerService} from 'backend/customer-service'; import {CommonDialogs} from 'resources/dialogs/common-dialogs'; import {EventAggregator} from 'aurelia-event-aggregator'; import {autoinject} from 'aurelia-framework'; @autoinject export class CustomerEditScreen { constructor(private customerService: CustomerService, private dialogs: CommonDialogs, private ea: EventAggregator) { this.customer = null; } activate(params) { return this.customerService.getCustomerById(params.customerId) .then(customer => this.customer = customer) .then(customer => this.ea.publish('edit', customer)); } }
If
you aren't using Babel's or TypeScript's decorator support (or don't want to), you can easily provide
injectmetadata
using a simple static method or property on your class:
如果babel和ts都不用,那么就这样添加依赖。用一个inject静态方法。
import {CustomerService} from 'backend/customer-service'; import {CommonDialogs} from 'resources/dialogs/common-dialogs'; import {EventAggregator} from 'aurelia-event-aggregator'; export class CustomerEditScreen { static inject() { return [CustomerService, CommonDialogs, EventAggregator]; } constructor(customerService, dialogs, ea) { this.customerService = customerService; this.dialogs = dialogs; this.ea = ea; this.customer = null; } activate(params) { return this.customerService.getCustomerById(params.customerId) .then(customer => this.customer = customer) .then(customer => this.ea.publish('edit:begin', customer)); } }
因为我们class文件里面的方法都是public或者private,我们想要使用必须对class进行实例化,只有static可以直接使用,
所以需要注入依赖实例化后才能调用。
相关文章推荐
- 07 Spring框架 依赖注入(四)基于注解的依赖注入
- spring入门(6)---set方法注入依赖之null的注入
- Spring 常用的几种依赖注入方式
- 依赖注入和控制反转的理解
- 微软企业库4.1学习笔记(二十六)Unity依赖注入模块3
- Android依赖注入:Google Guice on Android
- 好莱坞原则、依赖倒置、控制反转、依赖注入
- asp.net core-9.依赖注入的使用
- angularjs-依赖注入:显示注入和隐式注入
- spring依赖注入原理详解(转载)
- 控制反转(IoC)与依赖注入(DI)的学习资料
- 浅谈依赖注入
- spring DI 实现的模拟,依赖注入
- 使用dagger2进行依赖注入--简单入门,红色文字部分有意义
- 依赖注入6
- Spring依赖注入基础以及实现原理
- AngularJs依赖注入的研究
- 依赖注入
- Java之控制反转和依赖注入
- spring四种依赖注入方式