needle 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/manual/manual.yml +6 -1
- data/doc/manual/parts/customizing_contexts.txt +24 -0
- data/doc/manual/parts/customizing_interceptors.txt +38 -0
- data/doc/manual/parts/customizing_namespaces.txt +24 -0
- data/doc/manual-html/chapter-1.html +18 -2
- data/doc/manual-html/chapter-2.html +18 -2
- data/doc/manual-html/chapter-3.html +18 -2
- data/doc/manual-html/chapter-4.html +18 -2
- data/doc/manual-html/chapter-5.html +18 -2
- data/doc/manual-html/chapter-6.html +18 -2
- data/doc/manual-html/chapter-7.html +18 -2
- data/doc/manual-html/chapter-8.html +18 -2
- data/doc/manual-html/chapter-9.html +344 -0
- data/doc/manual-html/index.html +19 -3
- data/lib/needle/container.rb +4 -82
- data/lib/needle/definition-context.rb +100 -0
- data/lib/needle/registry.rb +19 -8
- data/lib/needle/version.rb +1 -1
- data/test/tc_container.rb +127 -86
- data/test/tc_definition_context.rb +75 -0
- data/test/tc_registry.rb +23 -0
- metadata +8 -2
data/doc/manual/manual.yml
CHANGED
@@ -23,7 +23,7 @@ product: !^product
|
|
23
23
|
- Needle Wiki: http://needle.rubyforge.org/wiki/wiki.pl
|
24
24
|
|
25
25
|
recent_updates:
|
26
|
-
-
|
26
|
+
- Added chapter on "Customizing Needle"
|
27
27
|
|
28
28
|
chapters:
|
29
29
|
|
@@ -70,3 +70,8 @@ chapters:
|
|
70
70
|
- Overview: !!file parts/libraries_overview.txt
|
71
71
|
- Creating Libraries: !!file parts/libraries_creating.txt
|
72
72
|
- Using Libraries: !!file parts/libraries_using.txt
|
73
|
+
|
74
|
+
- Customizing Needle:
|
75
|
+
- Namespaces: !!file parts/customizing_namespaces.txt
|
76
|
+
- Interceptors: !!file parts/customizing_interceptors.txt
|
77
|
+
- Contexts: !!file parts/customizing_contexts.txt
|
@@ -0,0 +1,24 @@
|
|
1
|
+
A _definition context_ is used when registering services using any of the @#define@ interfaces. For example, @Container#define@ yields an instance of a definition context to the given block, and @Container#define!@ uses the block in an @instance_eval@ on a definition context.
|
2
|
+
|
3
|
+
The default implementation used for definition contexts is defined by the @:definition_context_factory@ service. By default, this service returns @Needle::DefinitionContext@, but you can specify your own definition context implementations by overriding this service. In fact, each namespace could have its own definition context implementation, if needed.
|
4
|
+
|
5
|
+
Consider the following contrived example, where you want to provide a convenient way to register services of type Hash.
|
6
|
+
|
7
|
+
<pre>
|
8
|
+
class MyDefinitionContext < Needle::DefinitionContext
|
9
|
+
def register_hash( name, opts={} )
|
10
|
+
this_container.register( name, opts ) { Hash.new }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
reg = Needle::Registry.new
|
15
|
+
reg.register( :definition_context_factory ) { MyDefinitionContext }
|
16
|
+
|
17
|
+
reg.define do |b|
|
18
|
+
b.register_hash( :test1 )
|
19
|
+
b.register_hash( :test2 )
|
20
|
+
end
|
21
|
+
|
22
|
+
reg.test1[:key] = "value"
|
23
|
+
reg.test2[:foo] = "bar"
|
24
|
+
</pre>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
When you attach an interceptor to a service, that new interceptor is wrapped in a definition object that includes various metadata about the interceptor, including its implementation, its priority, its name, and so forth. The implementation of this interceptor definition is determined by the value of the @:interceptor_impl_factory@ service, which by default returns @Needle::Interceptor@.
|
2
|
+
|
3
|
+
It is this wrapper object that allows interceptor definitions to be done using method chaining:
|
4
|
+
|
5
|
+
<pre>
|
6
|
+
reg.intercept( :foo ).with { ... }.with_options(...)
|
7
|
+
</pre>
|
8
|
+
|
9
|
+
If you wish to add custom, domain-specific functionality to the interceptor wrapper, you can register your own implementation of the @:interceptor_impl_factory@. Consider the following contrived example, where an "only_if" clause is given to determine when the interceptor should be invoked.
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
class OnlyIfInterceptor < Needle::Interceptor
|
13
|
+
def only_if( &block )
|
14
|
+
@only_if = block
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def action
|
19
|
+
action_proc = super
|
20
|
+
lambda do |chain,ctx|
|
21
|
+
if @only_if.call( chain, ctx )
|
22
|
+
action_proc.call( chain, ctx )
|
23
|
+
else
|
24
|
+
chain.process_next( ctx )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
reg = Needle::Registry.new
|
31
|
+
reg.register( :interceptor_impl_factory ) { OnlyIfInterceptor }
|
32
|
+
reg.register( :foo ) { Bar.new }
|
33
|
+
|
34
|
+
reg.intercept( :foo ).
|
35
|
+
with { |c| c.logging_interceptor }.
|
36
|
+
only_if { |ch,ctx| something_is_true( ch, ctx ) }.
|
37
|
+
with_options(...)
|
38
|
+
</pre>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
By default, when you create a namespace in Needle, the namespace is registered as a service. The type of the service is determined by the @:namespace_impl_factory@ service, which (by default) returns the @Needle::Container@ class.
|
2
|
+
|
3
|
+
You can specify your own custom implementation for namespaces by registering your own @:namespace_impl_factory@ service. In fact, each namespace can have its own implementation of subnamespaces--just register a @:namespace_impl_factory@ in each one that you want to be specialized.
|
4
|
+
|
5
|
+
Here's a contrived example. Suppose you want each namespace to keep track of the precise time that it was created.
|
6
|
+
|
7
|
+
<pre>
|
8
|
+
class TimeTrackerNamespace < Needle::Container
|
9
|
+
attr_reader :birth_date
|
10
|
+
|
11
|
+
def initialize( *args )
|
12
|
+
super
|
13
|
+
@birth_date = Time.now
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
reg = Needle::Registry.new
|
18
|
+
reg.register( :namespace_impl_factory ) { TimeTrackerNamespace }
|
19
|
+
|
20
|
+
reg.namespace :hello
|
21
|
+
p reg.hello.birth_date
|
22
|
+
</pre>
|
23
|
+
|
24
|
+
In general, you'll be better off having your custom implementation extend @Needle::Container@, although the only _real_ requirement is that your implementation publish the same interface as the default namespace implementation.
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.
|
18
|
-
Manual Last Updated: <strong>2004-11-
|
17
|
+
Needle Version: <strong>1.1.0</strong><br />
|
18
|
+
Manual Last Updated: <strong>2004-11-11 17:31 GMT</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -166,6 +166,22 @@
|
|
166
166
|
</ol>
|
167
167
|
</li>
|
168
168
|
|
169
|
+
<li>
|
170
|
+
<a href="chapter-9.html">
|
171
|
+
Customizing Needle
|
172
|
+
</a>
|
173
|
+
|
174
|
+
<ol type="1">
|
175
|
+
|
176
|
+
<li><a href="chapter-9.html#s1">Namespaces</a></li>
|
177
|
+
|
178
|
+
<li><a href="chapter-9.html#s2">Interceptors</a></li>
|
179
|
+
|
180
|
+
<li><a href="chapter-9.html#s3">Contexts</a></li>
|
181
|
+
|
182
|
+
</ol>
|
183
|
+
</li>
|
184
|
+
|
169
185
|
</ol>
|
170
186
|
|
171
187
|
<h2>Other Documentation</h2>
|