needle 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/doc/manual-html/chapter-1.html +138 -78
  2. data/doc/manual-html/chapter-2.html +180 -99
  3. data/doc/manual-html/chapter-3.html +111 -75
  4. data/doc/manual-html/chapter-4.html +80 -48
  5. data/doc/manual-html/chapter-5.html +106 -56
  6. data/doc/manual-html/chapter-6.html +82 -34
  7. data/doc/manual-html/chapter-7.html +74 -38
  8. data/doc/manual-html/chapter-8.html +70 -41
  9. data/doc/manual-html/chapter-9.html +88 -63
  10. data/doc/manual-html/index.html +6 -6
  11. data/doc/manual-html/needle.png +0 -0
  12. data/doc/manual-html/{manual.css → stylesheets/manual.css} +83 -10
  13. data/doc/manual-html/stylesheets/ruby.css +17 -0
  14. data/doc/manual/chapter.erb +20 -0
  15. data/doc/manual/img/Needle.ai +0 -0
  16. data/doc/manual/img/needle.png +0 -0
  17. data/doc/manual/manual.rb +80 -5
  18. data/doc/manual/manual.yml +3 -3
  19. data/doc/manual/page.erb +1 -1
  20. data/doc/manual/parts/01_use_cases.txt +70 -70
  21. data/doc/manual/parts/02_creating.txt +19 -19
  22. data/doc/manual/parts/02_namespaces.txt +29 -29
  23. data/doc/manual/parts/02_services.txt +40 -41
  24. data/doc/manual/parts/03_conventional.txt +20 -20
  25. data/doc/manual/parts/03_locator.txt +44 -44
  26. data/doc/manual/parts/04_overview.txt +1 -1
  27. data/doc/manual/parts/04_setup.txt +32 -32
  28. data/doc/manual/parts/customizing_contexts.txt +14 -14
  29. data/doc/manual/parts/customizing_interceptors.txt +25 -25
  30. data/doc/manual/parts/customizing_namespaces.txt +12 -12
  31. data/doc/manual/parts/interceptors_attaching.txt +29 -30
  32. data/doc/manual/parts/interceptors_custom.txt +16 -16
  33. data/doc/manual/parts/interceptors_ordering.txt +5 -5
  34. data/doc/manual/parts/libraries_creating.txt +18 -18
  35. data/doc/manual/parts/libraries_using.txt +19 -19
  36. data/doc/manual/parts/logging_configuration.txt +13 -13
  37. data/doc/manual/parts/logging_logfactory.txt +21 -22
  38. data/doc/manual/parts/models_models.txt +8 -8
  39. data/doc/manual/parts/models_overview.txt +1 -1
  40. data/doc/manual/parts/models_pipelines.txt +22 -22
  41. data/doc/manual/{manual.css → stylesheets/manual.css} +83 -10
  42. data/doc/manual/stylesheets/ruby.css +17 -0
  43. data/lib/needle/definition-context.rb +3 -2
  44. data/lib/needle/lifecycle/proxy.rb +1 -1
  45. data/lib/needle/version.rb +1 -1
  46. metadata +94 -85
@@ -1,7 +1,7 @@
1
1
  <html>
2
2
  <head>
3
3
  <title>Needle Manual :: Chapter 6: Service Models</title>
4
- <link type="text/css" rel="stylesheet" href="manual.css" />
4
+ <link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
5
5
  </head>
6
6
 
7
7
  <body>
@@ -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.2.0</strong><br />
18
- Manual Last Updated: <strong>2004-11-18 15:36 GMT</strong>
17
+ Needle Version: <strong>1.2.1</strong><br />
18
+ Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -208,7 +208,17 @@
208
208
 
209
209
  <div id="content">
210
210
 
211
- <h1>6. Service Models</h1>
211
+ <div class="top"><div class="prevnext">
212
+
213
+ <a href="chapter-5.html">Previous (5. Interceptors)</a> |
214
+
215
+ <a href="index.html">Up</a>
216
+
217
+ | <a href="chapter-7.html">Next (7. Logging)</a>
218
+
219
+ </div></div>
220
+
221
+ <h1>6. Service Models</h1>
212
222
 
213
223
 
214
224
 
@@ -220,7 +230,8 @@
220
230
 
221
231
 
222
232
  <div class="section">
223
- <p>Service models are the mechanism by which a client can specify how the lifecycle of a particular service should be managed. By default, all services are managed as <em>singletons</em>, but it is a simple matter to choose a different behavior when a service is registered.</p>
233
+ <p>Service models are the mechanism by which a client can specify how the lifestyle of a particular service should be managed. By default, all services are managed as <em>singletons</em>, but it is a simple matter to choose a different behavior when a service is registered.</p>
234
+
224
235
 
225
236
  <p>Underneath, service models are implemented using an <em>instantiation pipeline</em>.</p>
226
237
  </div>
@@ -237,11 +248,16 @@
237
248
  <div class="section">
238
249
  <p>An <em>instantiation pipeline</em> is a sequence of elements, each of which knows how to perform some aspect of the instantiation of a service.</p>
239
250
 
240
- <p>Every service consists of at least one instantiation element&#8212;the block that was given when the service was registered. Other elements may be combined with this block to enforce various aspects of lifecycle management, such as <em>multiplicity</em> (singleton vs. prototype) and <em>laziness</em> (deferred vs. immediate instantiation).</p>
251
+
252
+ <p>Every service consists of at least one instantiation element&#8212;the block that was given when the service was registered. Other elements may be combined with this block to enforce various aspects of lifestyle management, such as <em>multiplicity</em> (singleton vs. prototype) and <em>laziness</em> (deferred vs. immediate instantiation).</p>
253
+
241
254
 
242
255
  <h3>Standard Pipeline Elements</h3>
243
256
 
244
- <p>There are five standard pipeline elements available in Needle (although you may certainly create your own):</p>
257
+
258
+ <p>There are six standard pipeline elements available in Needle (although you may certainly create your own):</p>
259
+
260
+
245
261
  <ul>
246
262
  <li><code>deferred</code>: this will always return a proxy that wraps subsequent pipeline elements, causing the subsequent elements to be executed only when a method is invoked on the proxy (at which point the method is then delegated to the resulting service).</li>
247
263
  <li><code>initialize</code>: this will invoke a method on the resulting service (defaults to <code>initialize_service</code>, though it can be changed). It is used for doing final initialization of services (for services that need it).</li>
@@ -251,56 +267,71 @@
251
267
  <li><code>threaded</code>: this is like the <code>singleton</code> element, but it ensures that a service is instantiated no more than once <em>per thread</em>.</li>
252
268
  </ul>
253
269
 
270
+
254
271
  <h3>Priorities</h3>
255
272
 
273
+
256
274
  <p>Just like interceptors, pipeline elements have priorities as well. These priorities determine the order in which the elements are executed in the pipeline.</p>
257
275
 
276
+
258
277
  <p>Each element type has a default priority, although that priority can be overridden when the element is added to the pipeline.</p>
259
278
 
279
+
260
280
  <h3>Custom Pipeline Elements</h3>
261
281
 
282
+
262
283
  <p>Creating new pipeline elements simple. Just create a new class that extends <code>Needle::Pipeline::Element</code>. Set the default pipeline priority (using the <code>#set_default_priority</code> class method), and then implement the <code>#call</code> method (accepting at least two parameters: the container and the service point).</p>
263
284
 
264
285
 
265
- <pre>
266
- require 'needle/pipeline/element'
286
+ <div class='figure'>
287
+ <span class='caption'>Custom pipeline element example [ruby]</span>
288
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">needle/pipeline/element</span><span class="punct">'</span>
289
+
290
+ <span class="keyword">class </span><span class="class">MyPipelineElement</span> <span class="punct">&lt;</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Pipeline</span><span class="punct">::</span><span class="constant">Element</span>
291
+ <span class="ident">set_default_priority</span> <span class="number">50</span>
292
+
293
+ <span class="keyword">def </span><span class="method">call</span><span class="punct">(</span> <span class="ident">container</span><span class="punct">,</span> <span class="ident">point</span><span class="punct">,</span> <span class="punct">*</span><span class="ident">args</span> <span class="punct">)</span>
294
+ <span class="punct">...</span>
295
+ <span class="ident">result</span> <span class="punct">=</span> <span class="ident">succ</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span> <span class="ident">container</span><span class="punct">,</span> <span class="ident">point</span><span class="punct">,</span> <span class="punct">*</span><span class="ident">args</span> <span class="punct">)</span>
296
+ <span class="punct">...</span>
297
+ <span class="keyword">return</span> <span class="ident">result</span>
298
+ <span class="keyword">end</span>
299
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
267
300
 
268
- class MyPipelineElement &lt; Needle::Pipeline::Element
269
- set_default_priority 50
270
301
 
271
- def call( container, point, *args )
272
- ...
273
- result = succ.call( container, point, *args )
274
- ...
275
- return result
276
- end
277
- end
278
- </pre>
279
302
  <p>To invoke the next element of the pipeline, just invoke <code>#succ.call(...)</code>.</p>
280
303
 
304
+
281
305
  <p>If needed, you can also implement <code>#initialize_element</code> (with no arguments), which you may invoke to perform initialization of the element. From there, you can access the options that were given to the element via the <code>#options</code> accessor.</p>
282
306
 
307
+
283
308
  <p>See the implementations of the existing elements in <code>needle/lifecycle</code> for examples.</p>
284
309
 
310
+
285
311
  <h3>Added Pipelines Elements to Services</h3>
286
312
 
313
+
287
314
  <p>You can specify the pipeline elements to use for a service via the <code>:pipeline</code> option. This must refer to an array, each element of which must be either a symbol (in which case it references an element of the <code>:pipeline_elements</code> service), or a class (in which case it must implement the interface required by @Needle::Pipeline::Element).</p>
288
315
 
289
316
 
290
- <pre>
291
- reg.register( :foo, :pipeline =&gt; [ :singleton, MyPipelineElement ] ) { ... }
292
- </pre>
317
+ <div class='figure'>
318
+ <span class='caption'>Adding pipelines to services [ruby]</span>
319
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:pipeline</span> <span class="punct">=&gt;</span> <span class="punct">[</span> <span class="symbol">:singleton</span><span class="punct">,</span> <span class="constant">MyPipelineElement</span> <span class="punct">]</span> <span class="punct">)</span> <span class="punct">{</span> <span class="punct">...</span> <span class="punct">}</span></pre></div></div></div>
320
+
321
+
293
322
  <p>The elements will be sorted based on their priorities, with lower priorities sorting closer to the instantiation block, and higher priorities sorting closer to the client.</p>
294
323
 
324
+
295
325
  <h3>Making Custom Pipeline Elements Available</h3>
296
326
 
327
+
297
328
  <p>You can make your custom pipeline elements available (so they can be referenced by symbol, instead of class name) by adding them to the <code>:pipeline_elements</code> service:</p>
298
329
 
299
330
 
300
- <pre>
301
- reg.pipeline_elements[ :my_pipeline_element ] = MyPipelineElement
302
- reg.register( :foo, :pipeline =&gt; [ :singleton, :my_pipeline_element ] ) { ... }
303
- </pre>
331
+ <div class='figure'>
332
+ <span class='caption'>Publishing custom pipeline elements [ruby]</span>
333
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">pipeline_elements</span><span class="punct">[</span> <span class="symbol">:my_pipeline_element</span> <span class="punct">]</span> <span class="punct">=</span> <span class="constant">MyPipelineElement</span>
334
+ <span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:pipeline</span> <span class="punct">=&gt;</span> <span class="punct">[</span> <span class="symbol">:singleton</span><span class="punct">,</span> <span class="symbol">:my_pipeline_element</span> <span class="punct">]</span> <span class="punct">)</span> <span class="punct">{</span> <span class="punct">...</span> <span class="punct">}</span></pre></div></td></tr></table></div></div>
304
335
  </div>
305
336
 
306
337
 
@@ -315,9 +346,11 @@
315
346
  <div class="section">
316
347
  <p>Specifying an entire pipeline for every service point can be tedious. For that reason, there are <em>service models</em>. A service model is a kind of template that names a pre-configured sequence of pipeline elements. Needle comes preconfigured with many service models.</p>
317
348
 
349
+
318
350
  <h3>Standard Service Models:</h3>
319
351
 
320
- <table style="border: 1px solid black;">
352
+
353
+ <table class="list">
321
354
  <tr>
322
355
  <th style="text-align:left;">Name</th>
323
356
  <th style="text-align:left;">Pipeline</th>
@@ -407,27 +440,42 @@
407
440
 
408
441
 
409
442
 
443
+
410
444
  <h3>Specifying a Service Model</h3>
411
445
 
446
+
412
447
  <p>You specify the service model by passing the <code>:model</code> option when you register a service. (You must only specify <em>either</em> the model, <em>or</em> the pipeline, but not both.)</p>
413
448
 
414
449
 
415
- <pre>
416
- reg.register( :foo, :model =&gt; :singleton_deferred ) {...}
417
- </pre>
450
+ <div class='figure'>
451
+ <span class='caption'>Specifying a service model [ruby]</span>
452
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:model</span> <span class="punct">=&gt;</span> <span class="symbol">:singleton_deferred</span> <span class="punct">)</span> <span class="punct">{...}</span></pre></div></div></div>
453
+
454
+
418
455
  <h3>Defining New Models</h3>
419
456
 
457
+
420
458
  <p>You can create your own service models by adding the corresponding pipelines to the <code>:service_models</code> service:</p>
421
459
 
422
460
 
423
- <pre>
424
- reg.service_models[ :my_service_model ] = [ :singleton, :my_pipeline_element ]
425
- reg.register( :foo, :model =&gt; :my_service_model ) {...}
426
- </pre>
461
+ <div class='figure'>
462
+ <span class='caption'>Defining a custom model [ruby]</span>
463
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">service_models</span><span class="punct">[</span> <span class="symbol">:my_service_model</span> <span class="punct">]</span> <span class="punct">=</span> <span class="punct">[</span> <span class="symbol">:singleton</span><span class="punct">,</span> <span class="symbol">:my_pipeline_element</span> <span class="punct">]</span>
464
+ <span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:model</span> <span class="punct">=&gt;</span> <span class="symbol">:my_service_model</span> <span class="punct">)</span> <span class="punct">{...}</span></pre></div></td></tr></table></div></div>
427
465
  </div>
428
466
 
429
467
 
430
468
 
469
+ <div class="bottom"><div class="prevnext">
470
+
471
+ <a href="chapter-5.html">Previous (5. Interceptors)</a> |
472
+
473
+ <a href="index.html">Up</a>
474
+
475
+ | <a href="chapter-7.html">Next (7. Logging)</a>
476
+
477
+ </div></div>
478
+
431
479
 
432
480
  </div>
433
481
 
@@ -1,7 +1,7 @@
1
1
  <html>
2
2
  <head>
3
3
  <title>Needle Manual :: Chapter 7: Logging</title>
4
- <link type="text/css" rel="stylesheet" href="manual.css" />
4
+ <link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
5
5
  </head>
6
6
 
7
7
  <body>
@@ -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.2.0</strong><br />
18
- Manual Last Updated: <strong>2004-11-18 15:36 GMT</strong>
17
+ Needle Version: <strong>1.2.1</strong><br />
18
+ Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -208,7 +208,17 @@
208
208
 
209
209
  <div id="content">
210
210
 
211
- <h1>7. Logging</h1>
211
+ <div class="top"><div class="prevnext">
212
+
213
+ <a href="chapter-6.html">Previous (6. Service Models)</a> |
214
+
215
+ <a href="index.html">Up</a>
216
+
217
+ | <a href="chapter-8.html">Next (8. Service Libraries)</a>
218
+
219
+ </div></div>
220
+
221
+ <h1>7. Logging</h1>
212
222
 
213
223
 
214
224
 
@@ -222,8 +232,10 @@
222
232
  <div class="section">
223
233
  <p>Logging is a pretty common activity in many applications. Because it is so common, Needle provides a powerful framework for logging messages in a consistent manner.</p>
224
234
 
235
+
225
236
  <p>Needle&#8217;s logging framework is built on top of the standard Ruby <code>Logger</code> library. However, it extends that library to add additional functionality, including customizable message formats and a centralized location for obtaining logger instances.</p>
226
237
 
238
+
227
239
  <p>This centralized location is the LogFactory.</p>
228
240
  </div>
229
241
 
@@ -240,43 +252,53 @@
240
252
  <p>The LogFactory is available as a service, so that any component that needs a logger instance can gain easy access to one. The factory&#8217;s service name is <code>:logs</code>.</p>
241
253
 
242
254
 
243
- <pre>
244
- factory = reg.logs
245
- </pre>
255
+ <div class='figure'>
256
+ <span class='caption'>Accessing the LogFactory service [ruby]</span>
257
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">factory</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">logs</span></pre></div></div></div>
258
+
259
+
246
260
  <p>You obtain logger instances from the factory by passing a logger name to <code>#get</code>:</p>
247
261
 
248
262
 
249
- <pre>
250
- logger = reg.logs.get "a logger name"
251
- </pre>
263
+ <div class='figure'>
264
+ <span class='caption'>Getting a named logger instance [ruby]</span>
265
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">logger</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">logs</span><span class="punct">.</span><span class="ident">get</span> <span class="punct">&quot;</span><span class="string">a logger name</span><span class="punct">&quot;</span></pre></div></div></div>
266
+
267
+
252
268
  <p>Subsequent calls to <code>#get</code> will return the same logger instance for the given logger name.</p>
253
269
 
270
+
254
271
  <h3>Loggers for Services</h3>
255
272
 
273
+
256
274
  <p>Typically, you&#8217;ll use this to assign a logger instance to a service when it is constructed. In that case, the name of the logger is the fully-qualified name of the service:</p>
257
275
 
258
276
 
259
- <pre>
260
- reg.register( :foo ) do |c,p|
261
- Foo.new( c.logs.get( p.fullname ) )
262
- end
263
- </pre>
277
+ <div class='figure'>
278
+ <span class='caption'>Getting a logger for a service [ruby]</span>
279
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">,</span><span class="ident">p</span><span class="punct">|</span>
280
+ <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">logs</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span> <span class="ident">p</span><span class="punct">.</span><span class="ident">fullname</span> <span class="punct">)</span> <span class="punct">)</span>
281
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
282
+
283
+
264
284
  <p>As a convenience, if the value passed to <code>#get</code> responds to either <code>fullname</code> or <code>name</code>, the return value of that message will be used as the name. Thus, you can do the following:</p>
265
285
 
266
286
 
267
- <pre>
268
- reg.register( :foo ) do |c,p|
269
- Foo.new( c.logs.get( p ) )
270
- end
271
- </pre>
287
+ <div class='figure'>
288
+ <span class='caption'>Getting a logger for a service (simplified) [ruby]</span>
289
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">,</span><span class="ident">p</span><span class="punct">|</span>
290
+ <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">logs</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span> <span class="ident">p</span> <span class="punct">)</span> <span class="punct">)</span>
291
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
292
+
293
+
272
294
  <p>As a further convenience, there is a <code>:log_for</code> service that is parameterized. Just pass the name of the log to retreive (or the service point instance) and it will return the log handle directly:</p>
273
295
 
274
296
 
275
- <pre>
276
- reg.register( :foo ) do |c,p|
277
- Foo.new( c.log_for( p ) )
278
- end
279
- </pre>
297
+ <div class='figure'>
298
+ <span class='caption'>Getting a logger for a service (simplified further) [ruby]</span>
299
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">,</span><span class="ident">p</span><span class="punct">|</span>
300
+ <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">log_for</span><span class="punct">(</span> <span class="ident">p</span> <span class="punct">)</span> <span class="punct">)</span>
301
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
280
302
  </div>
281
303
 
282
304
 
@@ -291,6 +313,7 @@
291
313
  <div class="section">
292
314
  <p>You can configure the LogFactory when you create the registry by passing a hash as the <code>:logs</code> option to <code>Registry.new</code>. The hash may have the following properties:</p>
293
315
 
316
+
294
317
  <table>
295
318
  <tr>
296
319
  <td style="vertical-align:top;"><code>:device</code></td>
@@ -332,29 +355,42 @@
332
355
 
333
356
 
334
357
 
358
+
335
359
  <p>By default, the filename is &#8221;./needle.log&#8221;, and the roll_size is one megabyte. The default level is <code>:debug</code>. If you wanted to specify a different filename and default level of <code>:warn</code>, you could do:</p>
336
360
 
337
361
 
338
- <pre>
339
- reg = Needle::Registry.new(
340
- :logs =&gt; {
341
- :filename =&gt; "./my-app.log",
342
- :default_level =&gt; :warn }
343
- )
344
- </pre>
362
+ <div class='figure'>
363
+ <span class='caption'>Configuring the loggers [ruby]</span>
364
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span>
365
+ <span class="symbol">:logs</span> <span class="punct">=&gt;</span> <span class="punct">{</span>
366
+ <span class="symbol">:filename</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">./my-app.log</span><span class="punct">&quot;,</span>
367
+ <span class="symbol">:default_level</span> <span class="punct">=&gt;</span> <span class="symbol">:warn</span> <span class="punct">}</span>
368
+ <span class="punct">)</span></pre></div></td></tr></table></div></div>
369
+
370
+
345
371
  <p>Alternatively, you can easily put the logging configuration in a <span class="caps">YAML</span> file and read it in, like so:</p>
346
372
 
347
373
 
348
- <pre>
349
- require 'yaml'
350
- reg = Needle::Registry.new(
351
- :logs =&gt; YAML.load( File.read( "log-conf.yml" ) )
352
- )
353
- </pre>
374
+ <div class='figure'>
375
+ <span class='caption'>Configuring the loggers from a YAML file [ruby]</span>
376
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">yaml</span><span class="punct">'</span>
377
+ <span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span>
378
+ <span class="symbol">:logs</span> <span class="punct">=&gt;</span> <span class="constant">YAML</span><span class="punct">.</span><span class="ident">load</span><span class="punct">(</span> <span class="constant">File</span><span class="punct">.</span><span class="ident">read</span><span class="punct">(</span> <span class="punct">&quot;</span><span class="string">log-conf.yml</span><span class="punct">&quot;</span> <span class="punct">)</span> <span class="punct">)</span>
379
+ <span class="punct">)</span></pre></div></td></tr></table></div></div>
354
380
  </div>
355
381
 
356
382
 
357
383
 
384
+ <div class="bottom"><div class="prevnext">
385
+
386
+ <a href="chapter-6.html">Previous (6. Service Models)</a> |
387
+
388
+ <a href="index.html">Up</a>
389
+
390
+ | <a href="chapter-8.html">Next (8. Service Libraries)</a>
391
+
392
+ </div></div>
393
+
358
394
 
359
395
  </div>
360
396
 
@@ -1,7 +1,7 @@
1
1
  <html>
2
2
  <head>
3
3
  <title>Needle Manual :: Chapter 8: Service Libraries</title>
4
- <link type="text/css" rel="stylesheet" href="manual.css" />
4
+ <link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
5
5
  </head>
6
6
 
7
7
  <body>
@@ -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.2.0</strong><br />
18
- Manual Last Updated: <strong>2004-11-18 15:36 GMT</strong>
17
+ Needle Version: <strong>1.2.1</strong><br />
18
+ Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
19
19
  </div>
20
20
  </td></tr>
21
21
  </table>
@@ -208,7 +208,17 @@
208
208
 
209
209
  <div id="content">
210
210
 
211
- <h1>8. Service Libraries</h1>
211
+ <div class="top"><div class="prevnext">
212
+
213
+ <a href="chapter-7.html">Previous (7. Logging)</a> |
214
+
215
+ <a href="index.html">Up</a>
216
+
217
+ | <a href="chapter-9.html">Next (9. Customizing Needle)</a>
218
+
219
+ </div></div>
220
+
221
+ <h1>8. Service Libraries</h1>
212
222
 
213
223
 
214
224
 
@@ -222,6 +232,7 @@
222
232
  <div class="section">
223
233
  <p>Using Needle as it has been presented so far works fine when you are dealing with a single application, all self-encapsulated. When you start dealing with combining multiple libraries, each potentially written by a different author, into a single registry, things get a little more complicated.</p>
224
234
 
235
+
225
236
  <p>Needle provides a way for service authors to share their services. All it requires is that authors centralize their service configuration.</p>
226
237
  </div>
227
238
 
@@ -237,33 +248,37 @@
237
248
  <div class="section">
238
249
  <p>This centralization is implemented by creating a module for each library you want to have services for. That module should then define a module function called (by default) <code>register_services</code>. This function should accept a single parameter&#8212;the Needle container that the services will be added to.</p>
239
250
 
251
+
240
252
  <p>For example, if I had a library of cryptographic routines and I wanted to make them accessible as Needle services, I would create a module to contain the service definitions. Typically, this module will be defined in a file called &#8220;services.rb&#8221;, although you can certainly name it whatever you like.</p>
241
253
 
242
254
 
243
- <pre>
244
- module Crypto
255
+ <div class='figure'>
256
+ <span class='caption'>Needle-enabled library example [ruby]</span>
257
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">module </span><span class="module">Crypto</span>
258
+
259
+ <span class="keyword">def </span><span class="method">register_services</span><span class="punct">(</span> <span class="ident">container</span> <span class="punct">)</span>
260
+ <span class="ident">container</span><span class="punct">.</span><span class="ident">namespace_define</span><span class="punct">(</span> <span class="symbol">:crypto</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
261
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">prng</span> <span class="keyword">do</span>
262
+ <span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/prng</span><span class="punct">'</span>
263
+ <span class="constant">PRNG</span><span class="punct">.</span><span class="ident">new</span>
264
+ <span class="keyword">end</span>
245
265
 
246
- def register_services( container )
247
- container.namespace_define( :crypto ) do |b|
248
- b.prng do
249
- require 'crypto/prng'
250
- PRNG.new
251
- end
266
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">des</span> <span class="keyword">do</span>
267
+ <span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/des</span><span class="punct">'</span>
268
+ <span class="constant">DES</span><span class="punct">.</span><span class="ident">new</span>
269
+ <span class="keyword">end</span>
252
270
 
253
- b.des do
254
- require 'crypto/des'
255
- DES.new
256
- end
271
+ <span class="punct">...</span>
272
+ <span class="keyword">end</span>
273
+ <span class="keyword">end</span>
274
+ <span class="ident">module_function</span> <span class="symbol">:register_services</span>
275
+
276
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
257
277
 
258
- ...
259
- end
260
- end
261
- module_function :register_services
262
278
 
263
- end
264
- </pre>
265
279
  <p>Notice that there are no explicit dependencies on Needle, only on the interfaces Needle publishes. Thus, third-parties can add service configuration modules to their libraries without introducing dependencies on Needle.</p>
266
280
 
281
+
267
282
  <p>Once a service library has been created, it can then be accessed from another library or application that wishes to import those services.</p>
268
283
  </div>
269
284
 
@@ -280,38 +295,52 @@
280
295
  <p>Using the libraries is as simple as requiring the file that has the service definitions, and then invoking the <code>#register_services</code> module function:</p>
281
296
 
282
297
 
283
- <pre>
284
- require 'needle'
298
+ <div class='figure'>
299
+ <span class='caption'>Example of using a Needle-enabled library [ruby]</span>
300
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">needle</span><span class="punct">'</span>
285
301
 
286
- reg = Needle::Registry.new
287
- reg.define do |b|
288
- b.foo { Foo.new }
302
+ <span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
303
+ <span class="ident">reg</span><span class="punct">.</span><span class="ident">define</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
304
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
305
+
306
+ <span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/services</span><span class="punct">'</span>
307
+ <span class="constant">Crypto</span><span class="punct">.</span><span class="ident">register_services</span><span class="punct">(</span> <span class="ident">reg</span> <span class="punct">)</span>
308
+ <span class="keyword">end</span>
309
+
310
+ <span class="ident">prng</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">crypto</span><span class="punct">.</span><span class="ident">prng</span></pre></div></td></tr></table></div></div>
289
311
 
290
- require 'crypto/services'
291
- Crypto.register_services( reg )
292
- end
293
312
 
294
- prng = reg.crypto.prng
295
- </pre>
296
313
  <p>To make this easier, the Container class has a convenience method named <code>#require</code>:</p>
297
314
 
298
315
 
299
- <pre>
300
- require 'needle'
316
+ <div class='figure'>
317
+ <span class='caption'>Example of using Container#require [ruby]</span>
318
+ <div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">needle</span><span class="punct">'</span>
319
+
320
+ <span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
321
+ <span class="ident">reg</span><span class="punct">.</span><span class="ident">define</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
322
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
323
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/services</span><span class="punct">',</span> <span class="punct">&quot;</span><span class="string">Crypto</span><span class="punct">&quot;</span>
324
+ <span class="keyword">end</span>
325
+
326
+ <span class="ident">prng</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">crypto</span><span class="punct">.</span><span class="ident">prng</span></pre></div></td></tr></table></div></div>
301
327
 
302
- reg = Needle::Registry.new
303
- reg.define do |b|
304
- b.foo { Foo.new }
305
- b.require 'crypto/services', "Crypto"
306
- end
307
328
 
308
- prng = reg.crypto.prng
309
- </pre>
310
329
  <p>The <code>Container#require</code> method will require the file, and then look for a <code>#register_services</code> method of the named module. It will execute that method, passing the container as an argument.</p>
311
330
  </div>
312
331
 
313
332
 
314
333
 
334
+ <div class="bottom"><div class="prevnext">
335
+
336
+ <a href="chapter-7.html">Previous (7. Logging)</a> |
337
+
338
+ <a href="index.html">Up</a>
339
+
340
+ | <a href="chapter-9.html">Next (9. Customizing Needle)</a>
341
+
342
+ </div></div>
343
+
315
344
 
316
345
  </div>
317
346