
瓶子JS
强大的依赖性注射微型容器
导言
BottleJS是一个微小而强大的依赖性注射容器. 它的特点是懒惰地装入,中器件钩子,装饰器和由受此启发的干净的阿皮 AngularJS 模块 API 和简单的 PHP 库 小猪你会喜欢瓶子JS的,如果你喜欢:
- 建起一个堆栈,而不是一个厨房-水槽框架.
- 无关联物体和依赖性注射.
- aPI是有意义的.
- 懒惰地装入物体.
- 尝试很酷的东西 : smile :
浏览器支持
BottleJS支持IE9+和其他ECMAScript 5兼容浏览器.
安装
BottleJS可用于浏览器或节点应用. 可通过弓形或npm安装:
$ bower install bottlejs
$ npm install bottlejs
Cdnjs上也有瓶子JS:
<script src="https://cdnjs.cloudflare.com/ajax/libs/bottlejs/1.7.1/bottle.min.js"></script>
简单示例
最简单的食谱开始于 Bottle#service。说你有一个服务对象的构造器:
var Beer = function() { /* A beer service, :yum: */ };
您可以用 Bottle#service数字 :
var bottle = new Bottle();
bottle.service('Beer', Beer);
稍后,当你需要构建的服务, 你只是访问 Beer 像这样的属性 :
bottle.container.Beer;
幕后发生了很多事:
- 瓶子在您注册啤酒服务时创建了一个包含工厂功能的供应商.
- 当
bottle.container.Beerbottle查了一下供货商 并处决了工厂 建造和归还啤酒服务. - 供应商和工厂被删除
bottle.container.Beer财产被设定为啤酒服务案例。 访问bottle.container.Beer将来会变成一个简单的财产查询.
注入依赖
以上例子很简单。 但是,如果啤酒服务 有依赖性呢? 例如:
var Barley = function() {};
var Hops = function() {};
var Water = function() {};
var Beer = function(barley, hops, water) { /* A beer service, :yum: */ };
您可以向您注册服务 Bottle#service 并包含此类依赖性:
var bottle = new Bottle();
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
bottle.service('Beer', Beer, 'Barley', 'Hops', 'Water');
现在,当你进入 bottle.container.Beer瓶子会轻而易举地装入所有依附物 并注入你的啤酒服务 然后再退货.
服务厂
如果您在生成服务时需要更复杂的逻辑,您可以注册工厂。 工厂功能接收容器作为论据,并应当返回您构建的服务:
var bottle = new Bottle();
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
bottle.factory('Beer', function(container) {
var barley = container.Barley;
var hops = container.Hops;
var water = container.Water;
barley.halved();
hops.doubled();
water.spring();
return new Beer(barley, hops, water);
});
服务提供者
这是瓶子库的肉. 上述方法 Bottle#service 财务报告和审定财务报表 Bottle#factory 仅是提供者函数的快手。 通常您可以通过上面的简单函数,但是如果您真的需要在不同环境中对您的服务进行更颗粒化的控制,请将其注册为提供者. 为了使用它,通过一个建筑师 供供应商暴露 $get 函数。 这个 $get 函数用作构建您的服务的工厂.
var bottle = new Bottle();
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
bottle.provider('Beer', function() {
// This environment may not support water.
// We should polyfill it.
if (waterNotSupported) {
Beer.polyfillWater();
}
// this is the service factory.
this.$get = function(container) {
var barley = container.Barley;
var hops = container.Hops;
var water = container.Water;
barley.halved();
hops.doubled();
water.spring();
return new Beer(barley, hops, water);
};
});
装饰者
瓶子支持用 Bottle#decorator 方法。 瓶装装饰器只是简单的功能,在服务创建后在提供者阶段拦截服务,但在首次访问之前. 该函数应当返回服务,或者另一个要用作服务的对象.
var bottle = new Bottle();
bottle.service('Beer', Beer);
bottle.service('Wine', Wine);
bottle.decorator(function(service) {
// this decorator will be run for both Beer and Wine services.
service.stayCold();
return service;
});
bottle.decorator('Wine', function(wine) {
// this decorator will only affect the Wine service.
wine.unCork();
return wine;
});
中间软件
瓶子中件与装饰相类似,但每次从容器访问服务时都会被执行. 他们通过 服务案例和a next 函数 :
var bottle = new Bottle();
bottle.service('Beer', Beer);
bottle.middleware(function(service, next) {
// this middleware will be executed for all services
console.log('A service was accessed!');
next();
});
bottle.middleware('Beer', function(beer, next) {
// this middleware will only affect the Beer service.
console.log('Beer? Nice. Tip your bartender...');
next();
});
中间软件可以将一个错误对象传递到 next 函数,瓶会丢出错误:
var bottle = new Bottle();
bottle.service('Beer', Beer);
bottle.middleware('Beer', function(beer, next) {
if (beer.hasGoneBad()) {
return next(new Error('The Beer has gone bad!'));
}
next();
});
// results in Uncaught Error: The Beer has gone bad!(…)
薄膜瓶
如果在服务名中使用了点标记,瓶会生成嵌入式容器. 将根据给定的名称为您创建一个孤立的子容器:
var bottle = new Bottle();
var IPA = function() {};
bottle.service('Beer.IPA', IPA);
bottle.container.Beer; // this is a new Bottle.container object
bottle.container.Beer.IPA; // the service
bottle.factory('Beer.DoubleIPA', function (container) {
var IPA = container.IPA; // note the container in here is the nearest parent.
})
封闭的容器被隔离
嵌入式容器旨在提供不同包件之间的隔离. 这意味着在写作工厂时,您无法访问来自不同家长的嵌入式容器.
var bottle = new Bottle();
var IPA = function() {};
var Wort = function() {};
bottle.service('Ingredients.Wort', Wort);
bottle.factory('Beer.IPA', function(container) {
// container is `Beer`, not the root, so:
container.Wort; // undefined
container.Ingredients.Wort; // undefined
});
API 密码
瓶装
弹出( 名称)
曾取一瓶来. 如果一个名字被通过,瓶子会返回同样的例子. 调用瓶子构造器作为函数将调用并返回 Bottle.pop这样 Bottle.pop('Soda') === Bottle('Soda')
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 (可选) | 字符串 | 取出瓶名来. 如果通过,瓶子将在内部存储实例,如果 Bottle.pop 后被取同名. |
清除( 名称)
从瓶子的内部仓库中删除命名实例,如果存在的话。 随即发出的呼吁 Bottle.pop(name) 将返回一个新的实例。 如果没有给出姓名,所有已命名的实例都会被清除.
一般来说,只有在您打算与新的提供者,装饰者等重置瓶子时,例如测试设置时,才应当调用此功能.
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 (可选) | 字符串 | 取出瓶名来. 如果通过, 如果使用 Bottle.pop。如果不通过,所有已命名的内部实例都将被清除. |
列表(容器)
原型. list( )
原型. container.$list( )
用于列出集装箱上所有已登记常数、值和服务的名称。 必须将容器传递到全局静态版本 Bottle.list(bottle.container)。实例和集装箱版本返回在其中注册的服务.
返回一系列字符串.
| 参数 | 类型 | 细节 |
|---|---|---|
| 集装箱 (可选) | 对象 | A 类 bottle.container。仅在使用全球静态时才需要 Bottle.list 方法。 原型版本使用那个实例的容器,而容器版本则使用自己. |
配置
全局配置对象 .
| 财产 | 类型 | 默认 | 细节 |
|---|---|---|---|
| 严格 | 布尔 | false | 启用严格模式 。 目前仅核实自动注入的依赖性不是未定义的. |
瓶.原型
装饰器
由瓶子实例注册的装饰器收藏. 见 decorator(name, func) 下级
中间软件
瓶子实例注册的中相器件集. 见 middleware(name, func) 见下文.
筑巢
当点名用于定义服务时,由母瓶实例注册的嵌入瓶集合. 参见以上文献"巢"部分.
提供者映射
注册提供者名集. 瓶子在内部用它来确定 提供商是否已经即时化了它的例子。 见 provider(name, Provider) 见下文.
推迟
此瓶子实例已注册的一系列延期函数 。 见 defer(func) 见下文.
常数( 名称, 值)
曾经只在容器上添加一个读取值.
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 常相之名为相. 必须是每个瓶子的例子独有的. |
| 价值 | 混合 | 将定义为可假设但不可写入的值 . |
装饰器( 名称, func)
标记器(名称, func)
用于注册一个装饰器功能, 由提供者在创建时用于修改您的服务 . bottle.container.$decorator 是一种异名 bottle.decorator;这只允许您在嵌入的瓶子上添加一个装饰器.
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 (可选) | 字符串 | 此装饰器将影响服务的名称 。 如果没通过,所有服务都会通过. |
| 乐趣c | 函数 | 将接受服务作为第一个参数的函数 。 返回服务,或用作服务的新对象. |
推迟( 已关闭)
注册待执行的函数 Bottle#resolve 名为.
| 参数 | 类型 | 细节 |
|---|---|---|
| 乐趣c | 函数 | 函数待后取名. 将传递给 Bottle#resolve。 。 。 . |
文摘(服务)
立即立即提供各种服务并返回其实例 按实例的顺序排列.
| 参数 | 类型 | 细节 |
|---|---|---|
| 服务 | 阵列 | 各种服务应当立即进行. |
工厂(名称、工厂)
曾注册服务厂
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 服务名. 必须是每个瓶子的例子独有的. |
| 工厂 | 函数 | 一个应该返回服务对象的函数。 只有一次被调用;服务会是一个单通. 在创建服务时,通过一个容器实例允许依赖性注射. |
实例事实( 名称、 工厂)
曾经注册一个服务实例工厂,当被调用时会返回一个实例.
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 服务名. 必须是每个瓶子的例子独有的. |
| 工厂 | 函数 | 一个函数,该函数应返回一个完全配置的服务对象。 当创建新实例时, 此工厂函数将执行 。 过了一个集装箱的例子. |
var bottle = new Bottle();
var Hefeweizen = function(container) { return { abv: Math.random() * (6 - 4) + 4 }};
bottle.instanceFactory('Beer.Hefeweizen', Hefeweizen);
var hefeFactory = bottle.container.Beer.Hefeweizen; // This is an instance factory with a single `instance` method
var beer1 = hefeFactory.instance(); // Calls factory function to create a new instance
var beer2 = hefeFactory.instance(); // Calls factory function to create a second new instance
beer1 !== beer2 // true
这种模式对于基于请求的上下文对象存储状态或数据库连接等东西特别有用. 见Google Guice的文档 输入器 需要更多的实例.
中件( 名称, func)
用于注册中间软件函数 。 每次访问服务时都会执行此功能.
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 (可选) | 字符串 | 此中件将调用的服务的名称 。 如果没通过,所有服务都会通过. |
| 乐趣c | 函数 | 接受服务作为第一个参数的函数,以及 a next 函数作为第二个参数。 应执行 next() 允许堆栈中的其他中间软件执行。 瓶子会扔任何传递给 next 函数,即. next(new Error('error msg'))。 。 。 . |
提供者( 名称, 提供者)
用于注册服务供应商
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 服务名. 必须是每个瓶子的例子独有的. |
| 提供者 | 函数 | 一个构造器函数,将以单子即时化. 显示一个名为 $get 将被用作工厂 以即时服务. |
重置提供者( 名)
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 (可选) | 阵列 | 包含要重置的提供者名称的字符串 . |
用于重置提供者,供下个参考,以重新证实提供者。 若为 names parm 已通过,将仅重置命名的提供者 .
注册( Obj)
注册人(Obj)
用于根据Obj的属性登记服务、工厂、提供者或价值. bottle.container.$register 是一种异名 bottle.register;这使得工厂和提供商可以在容器上注册多种服务而不需要使用瓶子实例本身.
若为 Bottle.config.strict 设置为 true,如果注入的依赖性是 undefined。 。 。 .
| 参数 | 类型 | 细节 |
|---|---|---|
| 欧比 | 对象|函数 | 具有若干属性之一的物体或构造器:
|
解析( 数据)
执行任何已注册的延期函数 Bottle#defer。 。 。 .
| 参数 | 类型 | 细节 |
|---|---|---|
| 数据 (可选) | 混合 | 要传递到每个被推迟的函数作为第一个参数的值 . |
服务( 名称、 构造器 [, 依赖性 [,...]])
曾注册服务建筑师. 若为 Bottle.config.strict 设置为 true,如果注入的依赖性是 undefined。 。 。 .
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 服务名. 必须是每个瓶子的例子独有的. |
| 构造器 | 函数 | 一个构造器函数,将以单子即时化. |
| 依赖性 (可选) | 字符串 | 一个可选的名称,用于将依赖性传递给构建者 。 将每个名称转给构造者 Bottle#service 按排列顺序排列. |
服务事实( 名称, 工厂服务 [, 依赖性 [,...]])
曾注册服务工厂功能. 完全一样 factory 除了工厂的参数会被注入而不是接收 container。这在执行模块模式或为您的高阶函数添加依赖性时是有用的.
function packageKeg(Barrel, Beer, Love) {
Barrel.add(Beer, Love);
return {
tap : function() {
return Barrel.dispense();
}
};
}
bottle.serviceFactory('Keg', packageKeg, 'Barrel', 'Beer', 'Love');
若为 Bottle.config.strict 设置为 true,如果注入的依赖性是 undefined。 。 。 .
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 服务名. 必须是每个瓶子的例子独有的. |
| 服务事实 | 函数 | 用于创建服务对象/值的函数. |
| 依赖性 (可选) | 字符串 | 将依赖性传递到服务函数的可选名称 。 对每个名称的依赖将传递给服务职能 Bottle#serviceFactory 按排列顺序排列. |
值( 名称, val)
曾为容器添加任意值.
| 参数 | 类型 | 细节 |
|---|---|---|
| 名称 | 字符串 | 值所取之名. 必须是每个瓶子的例子独有的. |
| val 时 | 混合 | 将定义为可假设但不可写入的值 . |
类型脚本
TypeScript 声明文件被捆绑在这个包中. 要让 TypeScript 自动解析, 您需要设置 moduleResolution 改为 node 在你身边 tsconfig.json。 。 。 .
