-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpimple.js
169 lines (149 loc) · 5.8 KB
/
pimple.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
* pimple.js - Javascript implementation of Fabien Potencier's Pimple simple Dependency Injection Container.
*
* @author Dario Mancuso
* @copyright 2009 Fabien Potencier (pimple.php - https://github.com/fabpot/Pimple)
* @copyright 2012 Dario Mancuso (Javascript port)
* @license http://opensource.org/licenses/mit-license.php MIT License
* @link https://github.com/dario1985
*/
(function () {
if (!window.Exception) {
window.Exception = function (m) {}
window.Exception.prototype = new Error();
}
if (!window.InvalidArgumentException) {
window.InvalidArgumentException = function (m) {}
window.InvalidArgumentException.prototype = new Exception();
}
window.Pimple = function (values) {
var values = values || {};
/**
* Sets a parameter or an object.
*
* Objects must be defined as Closures.
*
* Allowing any callable leads to difficult to debug problems
* as function names (strings) are callable (creating a function with
* the same a name as an existing parameter would break your container).
*
* @param string id The unique identifier for the parameter or object
* @param mixed value The value of the parameter or a closure to defined an object
*/
this.set = function (id, value) {
values[id] = value;
}
/**
* Gets a parameter or an object.
*
* @param string id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or an object
*
* @throws InvalidArgumentException if the identifier is not defined
*/
this.get = function (id) {
if (!(id in values)) {
throw new InvalidArgumentException('Identifier "' + id + '" is not defined.');
}
return (typeof(values[id]) == "function" ? values[id](this) : values[id]);
}
/**
* Checks if a parameter or an object is set.
*
* @param string id The unique identifier for the parameter or object
*
* @return Boolean
*/
this.exists = function (id) {
return (typeof(values[id]) != "undefined");
}
/**
* Unsets a parameter or an object.
*
* @param string id The unique identifier for the parameter or object
*/
this.unset = function (id) {
delete(values[id]);
}
/**
* Returns a closure that stores the result of the given closure for
* uniqueness in the scope of this instance of Pimple.
*
* @param Closure callable A closure to wrap for uniqueness
*
* @return Closure The wrapped closure
*/
this.share = function (callable) {
if (typeof(callable) != "function") {
throw new InvalidArgumentException('First argument is expected to be a valid callback');
}
var fn = callable;
return function (c) {
arguments.callee._object = arguments.callee._object || fn(c)
return arguments.callee._object;
};
}
/**
* Protects a callable from being interpreted as a service.
*
* This is useful when you want to store a callable as a parameter.
*
* @param Closure callable A closure to protect from being evaluated
*
* @return Closure The protected closure
*/
this.protect = function (callable) {
if (typeof(callable) != "function") {
throw new InvalidArgumentException('First argument is expected to be a valid callback');
}
var fn = callable;
return function (c) {
return fn;
};
}
/**
* Gets a parameter or the closure defining an object.
*
* @param string id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or the closure defining an object
*
* @throws InvalidArgumentException if the identifier is not defined
*/
this.raw = function (id) {
if (!(id in values)) {
throw new InvalidArgumentException('Identifier "' + id + '" is not defined.');
}
return values[id];
}
/**
* Extends an object definition.
*
* Useful when you want to extend an existing object definition,
* without necessarily loading that object.
*
* @param string id The unique identifier for the object
* @param Closure callable A closure to extend the original
*
* @return Closure The wrapped closure
*
* @throws InvalidArgumentException if the identifier is not defined
*/
this.extend = function (id, callable) {
if (!(id in values)) {
throw new InvalidArgumentException('Identifier "' + id + '" is not defined.');
}
if (typeof(callable) != "function") {
throw new InvalidArgumentException('Second argument is expected to be a valid callback');
}
var factory = values[id], fn = callable;
if (typeof(factory) != "function") {
throw new InvalidArgumentException('Identifier "' + id + '" does not contain an object definition.');
}
return values[id] = function (c) {
return fn(factory(c), c);
};
}
}
})()