needle 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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