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 1: Introduction</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,15 @@
208
208
 
209
209
  <div id="content">
210
210
 
211
- <h1>1. Introduction</h1>
211
+ <div class="top"><div class="prevnext">
212
+
213
+ <a href="index.html">Up</a>
214
+
215
+ | <a href="chapter-2.html">Next (2. Registry)</a>
216
+
217
+ </div></div>
218
+
219
+ <h1>1. Introduction</h1>
212
220
 
213
221
 
214
222
 
@@ -235,143 +243,180 @@
235
243
  <div class="section">
236
244
  <p>So, what can Needle do for you? Ultimately, it can reduce the amount of code that you have to write, simplifying many common programming tasks for you. This has the two-fold benefit of both decreasing application development time, and of decreasing the effort needed to maintain your application.</p>
237
245
 
246
+
238
247
  <p>But what, <em>specifically</em>, can Needle do for you?</p>
239
248
 
249
+
240
250
  <p>Try these on for size:</p>
251
+
252
+
241
253
  <ul>
242
254
  <li><a href="#logexec">Log Method Execution</a></li>
243
255
  <li><a href="#refsvc">Reference Another Service</a></li>
244
256
  <li><a href="#unittest">Unit Testing</a></li>
245
- <li><a href="#lifecycle">Lifecycle Management</a></li>
257
+ <li><a href="#lifestyle">Lifestyle Management</a></li>
246
258
  </ul>
247
259
 
260
+
248
261
  <p>(Thanks to Howard Lewis Ship for his <a href="http://jakarta.apache.org/hivemind">HiveMind</a> documentation, from which some of the above bullet points were adapted.)</p>
249
262
 
263
+
250
264
  <h3>Log Method Execution <a name="#logexec"></a></h3>
251
265
 
266
+
252
267
  <p>Needle has an integrated logging framework, and the ability to log execution trace information without modifying a single line of code in your classes. This means that you can easily see what methods get called, with what arguments, and what the return values are, all without having to physically modify any of your classes.</p>
253
268
 
269
+
254
270
  <p>Consider the following code, demonstrating how this would be done without Needle:</p>
255
271
 
256
272
 
257
- <pre>
258
- def foo( arg1, arg2 )
259
- @log.debug( "in foo with #{arg1} and #{arg2}" ) if @log.debug?
260
- ...
261
- result = the_result_of_the_method
262
- @log.debug( "finishing foo with #{result}" ) if @log.debug
263
- return result
264
- rescue Exception =&gt; e
265
- @log.debug( "foo raised exception #{e.message} (#{e.class})" ) if @log.debug?
266
- raise
267
- end
268
- </pre>
273
+ <div class='figure'>
274
+ <span class='caption'>Logging method execution without Needle [ruby]</span>
275
+ <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 /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">def </span><span class="method">foo</span><span class="punct">(</span> <span class="ident">arg1</span><span class="punct">,</span> <span class="ident">arg2</span> <span class="punct">)</span>
276
+ <span class="attribute">@log</span><span class="punct">.</span><span class="ident">debug</span><span class="punct">(</span> <span class="punct">&quot;</span><span class="string">in foo with <span class="expr">#{arg1}</span> and <span class="expr">#{arg2}</span></span><span class="punct">&quot;</span> <span class="punct">)</span> <span class="keyword">if</span> <span class="attribute">@log</span><span class="punct">.</span><span class="ident">debug?</span>
277
+ <span class="punct">...</span>
278
+ <span class="ident">result</span> <span class="punct">=</span> <span class="ident">the_result_of_the_method</span>
279
+ <span class="attribute">@log</span><span class="punct">.</span><span class="ident">debug</span><span class="punct">(</span> <span class="punct">&quot;</span><span class="string">finishing foo with <span class="expr">#{result}</span></span><span class="punct">&quot;</span> <span class="punct">)</span> <span class="keyword">if</span> <span class="attribute">@log</span><span class="punct">.</span><span class="ident">debug</span>
280
+ <span class="keyword">return</span> <span class="ident">result</span>
281
+ <span class="keyword">rescue</span> <span class="constant">Exception</span> <span class="punct">=&gt;</span> <span class="ident">e</span>
282
+ <span class="attribute">@log</span><span class="punct">.</span><span class="ident">debug</span><span class="punct">(</span> <span class="punct">&quot;</span><span class="string">foo raised exception <span class="expr">#{e.message}</span> (<span class="expr">#{e.class}</span>)</span><span class="punct">&quot;</span> <span class="punct">)</span> <span class="keyword">if</span> <span class="attribute">@log</span><span class="punct">.</span><span class="ident">debug?</span>
283
+ <span class="keyword">raise</span>
284
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
285
+
286
+
269
287
  <p>Now, multiply that by the number of methods in your class&#8230; the logging messages quickly overpower the rest of the code, and detract from the flow of your program. This makes your program harder to debug, test, and maintain.</p>
270
288
 
289
+
271
290
  <p>Now, consider the same method using Needle&#8217;s integrated logging framework&#8230;</p>
272
291
 
273
292
 
274
- <pre>
275
- def foo( arg1, arg2 )
276
- ...
277
- return the_result_of_the_method
278
- end
279
- </pre>
293
+ <div class='figure'>
294
+ <span class='caption'>Logging method execution with Needle [ruby]</span>
295
+ <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="keyword">def </span><span class="method">foo</span><span class="punct">(</span> <span class="ident">arg1</span><span class="punct">,</span> <span class="ident">arg2</span> <span class="punct">)</span>
296
+ <span class="punct">...</span>
297
+ <span class="keyword">return</span> <span class="ident">the_result_of_the_method</span>
298
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
299
+
300
+
280
301
  <p>Then, when you define the service that you want to add the logging to:</p>
281
302
 
282
303
 
283
- <pre>
284
- registry.register( :service_name_here ) { |reg| ... }
285
- registry.intercept( :service_name_here ).with! { logging_interceptor }
286
- </pre>
304
+ <div class='figure'>
305
+ <span class='caption'>Adding the logging interceptor to a service [ruby]</span>
306
+ <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">registry</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:service_name_here</span> <span class="punct">)</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">reg</span><span class="punct">|</span> <span class="punct">...</span> <span class="punct">}</span>
307
+ <span class="ident">registry</span><span class="punct">.</span><span class="ident">intercept</span><span class="punct">(</span> <span class="symbol">:service_name_here</span> <span class="punct">).</span><span class="ident">with!</span> <span class="punct">{</span> <span class="ident">logging_interceptor</span> <span class="punct">}</span></pre></div></td></tr></table></div></div>
308
+
309
+
287
310
  <p>That&#8217;s right. There&#8217;s no explicit logging code in there. Instead, you just tell Needle that the methods of the class should be logged, and away it goes. This has the added benefit of allowing your objects to be unit tested, without spewing log messages everywhere.</p>
288
311
 
312
+
289
313
  <h3>Reference Another Service <a name="#refsvc"></a></h3>
290
314
 
315
+
291
316
  <p>Invariably in a large application services will reference other services. This is typically accomplished through something like this:</p>
292
317
 
293
318
 
294
- <pre>
295
- class Component
296
- ...
297
- def foo( parms )
298
- @service ||= lookup_service
299
- @service.do_something( parms )
300
- end
301
-
302
- def lookup_service
303
- ...
304
- end
305
- ...
306
- end
307
- </pre>
319
+ <div class='figure'>
320
+ <span class='caption'>Looking up services without Needle [ruby]</span>
321
+ <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="keyword">class </span><span class="class">Component</span>
322
+ <span class="punct">...</span>
323
+ <span class="keyword">def </span><span class="method">foo</span><span class="punct">(</span> <span class="ident">parms</span> <span class="punct">)</span>
324
+ <span class="attribute">@service</span> <span class="punct">||=</span> <span class="ident">lookup_service</span>
325
+ <span class="attribute">@service</span><span class="punct">.</span><span class="ident">do_something</span><span class="punct">(</span> <span class="ident">parms</span> <span class="punct">)</span>
326
+ <span class="keyword">end</span>
327
+
328
+ <span class="keyword">def </span><span class="method">lookup_service</span>
329
+ <span class="punct">...</span>
330
+ <span class="keyword">end</span>
331
+ <span class="punct">...</span>
332
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
333
+
334
+
308
335
  <p>Whether the lookup is done lazily, as shown above, or when the class is first instantiated is irrelevant. The point is that you either have to implement a bunch of code to look up a service based on some criteria, or you hard code the class of the service (which creates tight coupling and makes things like unit testing harder).</p>
309
336
 
337
+
310
338
  <p>With Needle, you just declare a setter for the service, and then tell Needle that the class depends on the other service:</p>
311
339
 
312
340
 
313
- <pre>
314
- class Component
315
- attr_writer :service
316
- ...
317
- def foo( parms )
318
- @service.do_something( parms )
319
- end
320
- ...
321
- end
322
-
323
- registry.register( :component ) do |reg|
324
- c = Component.new
325
- c.service = reg.some_other_service
326
- c
327
- end
328
- </pre>
341
+ <div class='figure'>
342
+ <span class='caption'>Wiring services with Needle [ruby]</span>
343
+ <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 /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">class </span><span class="class">Component</span>
344
+ <span class="ident">attr_writer</span> <span class="symbol">:service</span>
345
+ <span class="punct">...</span>
346
+ <span class="keyword">def </span><span class="method">foo</span><span class="punct">(</span> <span class="ident">parms</span> <span class="punct">)</span>
347
+ <span class="attribute">@service</span><span class="punct">.</span><span class="ident">do_something</span><span class="punct">(</span> <span class="ident">parms</span> <span class="punct">)</span>
348
+ <span class="keyword">end</span>
349
+ <span class="punct">...</span>
350
+ <span class="keyword">end</span>
351
+
352
+ <span class="ident">registry</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:component</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">reg</span><span class="punct">|</span>
353
+ <span class="ident">c</span> <span class="punct">=</span> <span class="constant">Component</span><span class="punct">.</span><span class="ident">new</span>
354
+ <span class="ident">c</span><span class="punct">.</span><span class="ident">service</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">some_other_service</span>
355
+ <span class="ident">c</span>
356
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
357
+
358
+
329
359
  <p>Then, when your service is instantiated, Needle will automatically look for and instantiate the dependencies for you. This makes for cleaner code, and looser coupling between services.</p>
330
360
 
361
+
331
362
  <h3>Unit Testing <a name="#unittest"></a></h3>
332
363
 
364
+
333
365
  <p>Large applications can prove troublesome to unit test exhaustively, especially if there is any kind of tight coupling between components. Such coupling of components can make it difficult to test them separately.</p>
334
366
 
367
+
335
368
  <p>Needle, by its very nature, encourages loose coupling of components. Also, because dependencies are never instantiated in code, but are instead accepted via setters or constructor arguments, it is trivial to replace those dependencies with mock objects at unit test time.</p>
336
369
 
370
+
337
371
  <p>Consider this tightly coupled example:</p>
338
372
 
339
373
 
340
- <pre>
341
- def foo( args )
342
- @some_dependency ||= MyNewDependency.new
343
- @some_dependency.do_something(args)
344
- end
345
- </pre>
374
+ <div class='figure'>
375
+ <span class='caption'>Tight coupling [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="keyword">def </span><span class="method">foo</span><span class="punct">(</span> <span class="ident">args</span> <span class="punct">)</span>
377
+ <span class="attribute">@some_dependency</span> <span class="punct">||=</span> <span class="constant">MyNewDependency</span><span class="punct">.</span><span class="ident">new</span>
378
+ <span class="attribute">@some_dependency</span><span class="punct">.</span><span class="ident">do_something</span><span class="punct">(</span><span class="ident">args</span><span class="punct">)</span>
379
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
380
+
381
+
346
382
  <p>It is impossible to test the method <code>#foo</code> without also testing the MyNewDependency class. However, if the <code>@some_dependency</code> object is made a property that is set externally, you can replace it at test time with a blank:</p>
347
383
 
348
384
 
349
- <pre>
350
- attr_writer :some_dependency
385
+ <div class='figure'>
386
+ <span class='caption'>Loose coupling [ruby]</span>
387
+ <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">attr_writer</span> <span class="symbol">:some_dependency</span>
388
+
389
+ <span class="keyword">def </span><span class="method">foo</span><span class="punct">(</span> <span class="ident">args</span> <span class="punct">)</span>
390
+ <span class="attribute">@some_dependency</span><span class="punct">.</span><span class="ident">do_something</span><span class="punct">(</span> <span class="ident">args</span> <span class="punct">)</span>
391
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
392
+
351
393
 
352
- def foo( args )
353
- @some_dependency.do_something( args )
354
- end
355
- </pre>
356
394
  <p>The unit test would become something like this:</p>
357
395
 
358
396
 
359
- <pre>
360
- def test_foo
361
- @obj.some_dependecy = MyMockDependency.new
362
- @obj.foo( args )
363
- assert @obj.is_in_some_state
364
- end
365
- </pre>
366
- <h3>Lifecycle Management <a name="#lifecycle"></a></h3>
397
+ <div class='figure'>
398
+ <span class='caption'>Unit testing with a mock object [ruby]</span>
399
+ <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="keyword">def </span><span class="method">test_foo</span>
400
+ <span class="attribute">@obj</span><span class="punct">.</span><span class="ident">some_dependecy</span> <span class="punct">=</span> <span class="constant">MyMockDependency</span><span class="punct">.</span><span class="ident">new</span>
401
+ <span class="attribute">@obj</span><span class="punct">.</span><span class="ident">foo</span><span class="punct">(</span> <span class="ident">args</span> <span class="punct">)</span>
402
+ <span class="ident">assert</span> <span class="attribute">@obj</span><span class="punct">.</span><span class="ident">is_in_some_state</span>
403
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
404
+
405
+
406
+ <h3>Lifestyle Management <a name="#lifestyle"></a></h3>
407
+
367
408
 
368
409
  <p>Singleton objects are a fact of life in complex systems. The singleton design pattern is powerful and useful. However, using the Singleton mixin, or declaring methods at the class level, can make your code difficult to unit test since the state of such objects cannot be easily reset.</p>
369
410
 
411
+
370
412
  <p>Needle has a solution. You can tell Needle to treat a service as either a <em>prototype</em> service (meaning it will be instantiated every time you ask for it, like calling <code>#new</code>), or a <em>singleton</em> service (meaning it will only be instantiated once, and the same instance will be returned for subsequent requests).</p>
371
413
 
414
+
372
415
  <p>Your object is still just a plain ol&#8217; ordinary Ruby object, but Needle has effectively transformed it into a singleton. This means you can unit test it as if it were nothing special, but when it is used in your application it will act like a singleton.</p>
373
416
 
374
- <p>Lifecycle management also means that you can control <em>when</em> a service is instantiated. The <em>prototype</em> and <em>singleton</em> models will always be instantiated as soon as they are requested. Sometimes, though, you don&#8217;t want that&#8212;you&#8217;d like the instantiation to be deferred as late as possible.</p>
417
+
418
+ <p>Lifestyle management also means that you can control <em>when</em> a service is instantiated. The <em>prototype</em> and <em>singleton</em> models will always be instantiated as soon as they are requested. Sometimes, though, you don&#8217;t want that&#8212;you&#8217;d like the instantiation to be deferred as late as possible.</p>
419
+
375
420
 
376
421
  <p>With Needle, you can indicate that a service should use deferred instantiation. This will cause the service to not actually be instantiated until a method is actually invoked on it. Using this model, you can have services depend on themselves, or other forms of cyclical dependencies.</p>
377
422
  </div>
@@ -387,6 +432,8 @@
387
432
 
388
433
  <div class="section">
389
434
  <p>Needle is not the only fish in the dependency-injection pond, even when it comes to Ruby. Other containers at your disposal include:</p>
435
+
436
+
390
437
  <ul>
391
438
  <li><a href="http://copland.rubyforge.org">Copland</a>. Copland aims to be an &#8220;application framework&#8221;, taking something of a heavy-weight approach to DI. In so doing, it provides functionality that Needle does not, but at the cost of performance. It also uses external (YAML) configuration files. It is inspired by a Java framework (<a href="http://jakarta.apache.org/hivemind">HiveMind</a>), and so has a vaguely Java-ish flavor to it.</li>
392
439
  <li><a href="http://www.picocontainer.org/Rico">Rico</a>. Rico is another project inspired by a Java project (<a href="http://www.picocontainer.org">PicoContainer</a>). It is very lean, and appears to be experimental.</li>
@@ -394,10 +441,13 @@
394
441
  <li><a href="http://redshift.sourceforge.net/mindi/">MinDI</a> is a recent contender that takes a very novel approach to dependency injection. Instead of instantiating a container and adding services to it, you declare a class, mixin a DI module, and add services to the class as methods, thereby making the class the container.</li>
395
442
  </ul>
396
443
 
444
+
397
445
  <p>There is, at the time of this writing, at least one other project on RubyForge devoted to <span class="caps">DI </span>(<a href="http://rubyforge.org/projects/pith">Pith</a>), although it has no public releases yet.</p>
398
446
 
447
+
399
448
  <p>So, which one should you choose? It comes down to an issue of personal preference, mostly, but also one of what you are wanting to accomplish. Needle excels at providing an unobtrusive, light-weight container for managing your dependencies. The cost of it being light-weight is that there is functionality it does not provide, which other containers may. If you really need that missing functionality, you are required to either implement it yourself, or select a different container.</p>
400
449
 
450
+
401
451
  <p>For most tasks, I think you&#8217;ll find Needle more than sufficient.</p>
402
452
  </div>
403
453
 
@@ -413,8 +463,10 @@
413
463
  <div class="section">
414
464
  <p>Needle is made available under either the <span class="caps">BSD</span> license, or the same license Ruby (which, by extension, also allows the <span class="caps">GPL</span> as a permissable license as well). You can view the full text of any of these licenses in the <code>doc</code> subdirectory of the Needle distrubtion. The texts of the <span class="caps">BSD</span> and <span class="caps">GPL</span> licenses are also available online: <a href="http://www.opensource.org/licenses/bsd-license.php">BSD</a> and <a href="http://www.opensource.org/licenses/gpl-license.php">GPL</a>.</p>
415
465
 
466
+
416
467
  <p>This manual (in any form, be it source or otherwise) and the scripts and templates used to generate it, are all distributed under the <a href="http://creativecommons.org">Creative Commons</a> <a href="http://creativecommons.org/licenses/by-sa/2.0">Attribution-ShareAlike</a> license.</p>
417
468
 
469
+
418
470
  <p>If you desire permission to use either Needle or the manual in a manner incompatible with these licenses, please contact the copyright holder (<a href="mailto:jgb3@email.byu.edu">Jamis Buck</a>) in order to negotiate a more compatible license.</p>
419
471
  </div>
420
472
 
@@ -433,6 +485,14 @@
433
485
 
434
486
 
435
487
 
488
+ <div class="bottom"><div class="prevnext">
489
+
490
+ <a href="index.html">Up</a>
491
+
492
+ | <a href="chapter-2.html">Next (2. Registry)</a>
493
+
494
+ </div></div>
495
+
436
496
 
437
497
  </div>
438
498
 
@@ -1,7 +1,7 @@
1
1
  <html>
2
2
  <head>
3
3
  <title>Needle Manual :: Chapter 2: Registry</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>2. Registry</h1>
211
+ <div class="top"><div class="prevnext">
212
+
213
+ <a href="chapter-1.html">Previous (1. Introduction)</a> |
214
+
215
+ <a href="index.html">Up</a>
216
+
217
+ | <a href="chapter-3.html">Next (3. Service Locator)</a>
218
+
219
+ </div></div>
220
+
221
+ <h1>2. Registry</h1>
212
222
 
213
223
 
214
224
 
@@ -222,6 +232,7 @@
222
232
  <div class="section">
223
233
  <p>The registry is at the heart of any dependency-injected application or library. All services are registered with the registry, so that when an application needs an instance of a particular service, it may obtain that service reference by querying the registry.</p>
224
234
 
235
+
225
236
  <p>In order to use Needle, you only really <em>need</em> to understand how to create and manipulate registry objects.</p>
226
237
  </div>
227
238
 
@@ -238,41 +249,52 @@
238
249
  <p>Creating a registry is as simple as calling <code>Needle::Registry.new</code>. This will give you a new registry object, bootstrapped to contain a few general services.</p>
239
250
 
240
251
 
241
- <pre>
242
- require 'needle'
252
+ <div class='figure'>
253
+ <span class='caption'>Creating a registry [ruby]</span>
254
+ <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">require</span> <span class="punct">'</span><span class="string">needle</span><span class="punct">'</span>
255
+
256
+ <span class="ident">registry</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></pre></div></td></tr></table></div></div>
257
+
243
258
 
244
- registry = Needle::Registry.new
245
- </pre>
246
259
  <p>Once you have the reference to the registry, you can register services with it, create new namespaces in it, and so forth.</p>
247
260
 
261
+
248
262
  <p>Alternatively, you can pass a block to <code>#new</code>:</p>
249
263
 
250
264
 
251
- <pre>
252
- registry = Needle::Registry.new do |r|
253
- ...
254
- end
255
- </pre>
265
+ <div class='figure'>
266
+ <span class='caption'>Creating a registry with a block [ruby]</span>
267
+ <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">registry</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="keyword">do</span> <span class="punct">|</span><span class="ident">r</span><span class="punct">|</span>
268
+ <span class="punct">...</span>
269
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
270
+
271
+
256
272
  <p>The parameter to the block will be a reference to the registry. This allows you to register services with the registry as soon as it is created.</p>
257
273
 
274
+
258
275
  <p>Another convenience method is <code>#define!</code>:</p>
259
276
 
260
277
 
261
- <pre>
262
- registry = Needle::Registry.define! do
263
- ...
264
- end
265
- </pre>
278
+ <div class='figure'>
279
+ <span class='caption'>Creating a registry with #define! [ruby]</span>
280
+ <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">registry</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">define!</span> <span class="keyword">do</span>
281
+ <span class="punct">...</span>
282
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
283
+
284
+
266
285
  <p>This block accepts no parameters, and evaluates the block as if it were passed to <code>Registry#define!</code> (see below).</p>
267
286
 
287
+
268
288
  <p>There can be problems with using <code>define!</code>, however, since it uses <code>instance_eval</code> to evaluate the block within the context of another object. If you find yourself running into scoping issues, you might want to consider using <code>#define</code>:</p>
269
289
 
270
290
 
271
- <pre>
272
- registry = Needle::Registry.define do |b|
273
- ...
274
- end
275
- </pre>
291
+ <div class='figure'>
292
+ <span class='caption'>Creating a registry with #define [ruby]</span>
293
+ <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">registry</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">define</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
294
+ <span class="punct">...</span>
295
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
296
+
297
+
276
298
  <p>This block accepts a single parameter&#8212;a &#8220;builder&#8221; object to aid in registering services&#8212;and evaluates the block as if it were passed to <code>Registry#define</code> (see below).</p>
277
299
  </div>
278
300
 
@@ -289,91 +311,124 @@
289
311
  <p>Registering services with a Needle registry is very straightforward. The simplest way to do it is:</p>
290
312
 
291
313
 
292
- <pre>
293
- registry.register( :foo ) { Bar.new }
294
- </pre>
314
+ <div class='figure'>
315
+ <span class='caption'>Registering services [ruby]</span>
316
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">registry</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="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span></pre></div></div></div>
317
+
318
+
295
319
  <p>The above will register a new service with the registry, naming it <code>:foo</code>. When <code>:foo</code> is requested from the registry, a new instance of <code>Bar</code> will be instantiated and returned.</p>
296
320
 
321
+
297
322
  <p>You get services from the registry in either of two ways:</p>
298
323
 
299
324
 
300
- <pre>
301
- # Treating the registry as a Hash
302
- svc = registry[:foo]
325
+ <div class='figure'>
326
+ <span class='caption'>Accessing services [ruby]</span>
327
+ <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="comment"># Treating the registry as a Hash</span>
328
+ <span class="ident">svc</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">[</span><span class="symbol">:foo</span><span class="punct">]</span>
329
+
330
+ <span class="comment"># Treating the service as a property of the registry</span>
331
+ <span class="ident">svc</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">foo</span></pre></div></td></tr></table></div></div>
332
+
303
333
 
304
- # Treating the service as a property of the registry
305
- svc = registry.foo
306
- </pre>
307
334
  <h3>Convenience Methods</h3>
308
335
 
336
+
309
337
  <p>Because you will often need to register many services with a registry at once, two convenience methods have been provided to make this use case lean and mean.</p>
310
338
 
339
+
311
340
  <p>The first is <code>define</code>. Just pass a block to define that accepts one parameter. This parameter will be a &#8220;builder&#8221; object that allows you to define services just by sending them as messages to the builder:</p>
312
341
 
313
342
 
314
- <pre>
315
- registry.define do |b|
316
- b.foo { Bar.new }
317
- b.bar { Foo.new }
318
- ...
319
- end
320
- </pre>
343
+ <div class='figure'>
344
+ <span class='caption'>Defining services [ruby]</span>
345
+ <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">registry</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>
346
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
347
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">bar</span> <span class="punct">{</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
348
+ <span class="punct">...</span>
349
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
350
+
351
+
321
352
  <p>Alternative, you can call <code>define!</code>, passing a block that accepts no parameters. This block will be evaluated in the &#8220;builder&#8221; object&#8217;s context, with any unrecognized method call being interpreted as a new service registration of that name:</p>
322
353
 
323
354
 
324
- <pre>
325
- registry.define! do
326
- foo { Bar.new }
327
- bar { Foo.new }
328
- ...
329
- end
330
- </pre>
355
+ <div class='figure'>
356
+ <span class='caption'>Defining services via #define! [ruby]</span>
357
+ <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">registry</span><span class="punct">.</span><span class="ident">define!</span> <span class="keyword">do</span>
358
+ <span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
359
+ <span class="ident">bar</span> <span class="punct">{</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
360
+ <span class="punct">...</span>
361
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
362
+
363
+
331
364
  <p>Both of the above will register two new services with the registry, <code>:foo</code> and <code>:bar</code>.</p>
332
365
 
333
- <h3>Default Lifecycle</h3>
366
+
367
+ <h3>Default Lifestyle</h3>
368
+
334
369
 
335
370
  <p>By default, a service is only instantiated once per registry. This means that (using the above example) if the service <code>:foo</code> were queried twice, the registry would return the same object for both queries:</p>
336
371
 
337
372
 
338
- <pre>
339
- svc1 = registry.foo
340
- svc2 = registry.foo
373
+ <div class='figure'>
374
+ <span class='caption'>Demonstrating singleton service behavior [ruby]</span>
375
+ <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">svc1</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">foo</span>
376
+ <span class="ident">svc2</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">foo</span>
377
+
378
+ <span class="ident">p</span> <span class="ident">svc1</span><span class="punct">.</span><span class="ident">object_id</span> <span class="punct">==</span> <span class="ident">svc2</span><span class="punct">.</span><span class="ident">object_id</span> <span class="comment">#=&gt; true</span></pre></div></td></tr></table></div></div>
379
+
341
380
 
342
- p svc1.object_id == svc2.object_id #=&gt; true
343
- </pre>
344
381
  <p>You can change this behavior, with <em>service models</em>. See the chapter on Service Models for more information.</p>
345
382
 
383
+
346
384
  <h3>Parameterized Services</h3>
347
385
 
386
+
348
387
  <p>Needle also supports <em>parameterized services</em>. These are services that, when requested, require contextual information to be passed as a parameter so that the service can be correctly initialized.</p>
349
388
 
389
+
350
390
  <p>Consider the following example, in which some hypothetical <code>Printer</code> class represents any of a number of printers, based on a parameter given to its constructor.</p>
351
391
 
352
392
 
353
- <pre>
354
- registry.register( :printer, :model =&gt; :multiton ) do |c,p,name|
355
- Printer.new( c.log_for( p ), name )
356
- end
393
+ <div class='figure'>
394
+ <span class='caption'>Parameterized services [ruby]</span>
395
+ <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 /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">registry</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:printer</span><span class="punct">,</span> <span class="symbol">:model</span> <span class="punct">=&gt;</span> <span class="symbol">:multiton</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><span class="ident">name</span><span class="punct">|</span>
396
+ <span class="constant">Printer</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="ident">name</span> <span class="punct">)</span>
397
+ <span class="keyword">end</span>
398
+
399
+ <span class="ident">mono</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">printer</span><span class="punct">(</span> <span class="symbol">:monochrome</span> <span class="punct">)</span>
400
+ <span class="ident">color</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">printer</span><span class="punct">(</span> <span class="symbol">:color</span> <span class="punct">)</span></pre></div></td></tr></table></div></div>
401
+
357
402
 
358
- mono = registry.printer( :monochrome )
359
- color = registry.printer( :color )
360
- </pre>
361
403
  <p>There are a few things to note about the above example:</p>
404
+
405
+
406
+ <ol>
407
+ <li>The <code>:multiton</code> model is explicitly requested. This is necessary because the default service model (<code>:singleton</code>) does not allow parameterized services. Most of the time, you&#8217;ll use the multiton service model with parameterized services, but you don&#8217;t have to. You could also use any of the prototype models as well.</li>
408
+ </ol>
409
+
410
+
411
+ <ol>
412
+ <li>The constructor block for the <code>:printer</code> service takes three parameters, <code>c</code>, <code>p</code>, and <code>name</code>. The first two parameters, <code>c</code> and <code>p</code>, represent the container and the service point, respectively. Any parameters after those two are the contextual parameters given when the service is requested. In this case, there is only one contextual parameter: the name of the printer.</li>
413
+ </ol>
414
+
415
+
362
416
  <ol>
363
- <li>The <code>:multiton</code> model is explicitly requested. This is necessary because the default service model (<code>:singleton</code>) does not allow parameterized services. Most of the time, you&#8217;ll use the multiton service model with parameterized services, but you don&#8217;t have to. You could also use any of the prototype models as well.
364
- </li>
365
- <li>The constructor block for the <code>:printer</code> service takes three parameters, <code>c</code>, <code>p</code>, and <code>name</code>. The first two parameters, <code>c</code> and <code>p</code>, represent the container and the service point, respectively. Any parameters after those two are the contextual parameters given when the service is requested. In this case, there is only one contextual parameter: the name of the printer.
366
- </li>
367
- <li>Notice the first parameter to the Printer constructor: <code>c.log_for(p)</code>. This is itself invoking a parameterized service, named <code>:log_for</code>, and passing <code>p</code> as the contextual information. This will return a new logger handle for the service point <code>p</code> (i.e., the current service point).
368
- </li>
369
- <li>See how the printer service is requested on the last two lines. In this case, the <code>#printer</code> message is sent to the registry with a single parameter. You can also request the service in two other ways:</li>
417
+ <li>Notice the first parameter to the Printer constructor: <code>c.log_for(p)</code>. This is itself invoking a parameterized service, named <code>:log_for</code>, and passing <code>p</code> as the contextual information. This will return a new logger handle for the service point <code>p</code> (i.e., the current service point).</li>
370
418
  </ol>
371
419
 
372
420
 
373
- <pre>
374
- dot_matrix = registry[ :printer, :dot_matrix ]
375
- ink_jet = registry.get( :printer, :ink_jet )
376
- </pre>
421
+ <ol>
422
+ <li>See how the printer service is requested on the last two lines. In this case, the <code>#printer</code> message is sent to the registry with a single parameter. You can also request the service in two other ways:</li>
423
+ </ol>
424
+
425
+
426
+ <div class='figure'>
427
+ <span class='caption'>Accessing parameterized services [ruby]</span>
428
+ <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">dot_matrix</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">[</span> <span class="symbol">:printer</span><span class="punct">,</span> <span class="symbol">:dot_matrix</span> <span class="punct">]</span>
429
+ <span class="ident">ink_jet</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span> <span class="symbol">:printer</span><span class="punct">,</span> <span class="symbol">:ink_jet</span> <span class="punct">)</span></pre></div></td></tr></table></div></div>
430
+
431
+
377
432
  <p>Choose the style that works best for you.</p>
378
433
  </div>
379
434
 
@@ -388,66 +443,92 @@
388
443
 
389
444
  <div class="section">
390
445
  <p>Namespaces allow you to organize your services. The feature has many different applications, including:</p>
446
+
447
+
391
448
  <ol>
392
449
  <li>Third-parties may distribute Needle-enabled libraries without worrying about their choice of service names conflicting with the service names of their clients.</li>
393
450
  <li>Developers may organize complex applications into modules, and the service definitions may be stored in the registry to reflect that organization.</li>
394
451
  <li>Services deeper in the hierarchy may override services higher up.</li>
395
452
  </ol>
396
453
 
454
+
397
455
  <p>Creating a namespace is as easy as invoking the <code>#namespace</code> method of the registry (or of another namespace):</p>
398
456
 
399
457
 
400
- <pre>
401
- registry.namespace :stuff
402
- </pre>
458
+ <div class='figure'>
459
+ <span class='caption'>Creating a namespace [ruby]</span>
460
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">registry</span><span class="punct">.</span><span class="ident">namespace</span> <span class="symbol">:stuff</span></pre></div></div></div>
461
+
462
+
403
463
  <p>This would create a new namespace in the registry called <code>:stuff</code>. The application may then proceed to register services inside that namespace:</p>
404
464
 
405
465
 
406
- <pre>
407
- registry.stuff.register( :foo ) { Bar.new }
408
- ...
409
- svc = registry.stuff.foo
410
- </pre>
466
+ <div class='figure'>
467
+ <span class='caption'>Registering services in a namespace [ruby]</span>
468
+ <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">registry</span><span class="punct">.</span><span class="ident">stuff</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="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
469
+ <span class="punct">...</span>
470
+ <span class="ident">svc</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">.</span><span class="ident">stuff</span><span class="punct">.</span><span class="ident">foo</span></pre></div></td></tr></table></div></div>
471
+
472
+
411
473
  <p>Here&#8217;s a tip: <em>namespaces are just a special kind of service.</em> This means that you can access namespaces in the same ways that you can access services:</p>
412
474
 
413
475
 
414
- <pre>
415
- svc = registry[:stuff][:foo]
416
- </pre>
476
+ <div class='figure'>
477
+ <span class='caption'>Accessing a namespace [ruby]</span>
478
+ <div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">svc</span> <span class="punct">=</span> <span class="ident">registry</span><span class="punct">[</span><span class="symbol">:stuff</span><span class="punct">][</span><span class="symbol">:foo</span><span class="punct">]</span></pre></div></div></div>
479
+
480
+
417
481
  <h3>Convenience Methods</h3>
418
482
 
483
+
419
484
  <p>Because it is often the case that you will be creating a namespace and then immediately registering services on it, you can pass a block to <code>namespace</code>. The block will receive a reference to the new namespace:</p>
420
485
 
421
486
 
422
- <pre>
423
- registry.namespace :stuff do |spc|
424
- spc.register( :foo ) { Bar.new }
425
- ...
426
- end
427
- </pre>
487
+ <div class='figure'>
488
+ <span class='caption'>More registering services in a namespace [ruby]</span>
489
+ <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">registry</span><span class="punct">.</span><span class="ident">namespace</span> <span class="symbol">:stuff</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">spc</span><span class="punct">|</span>
490
+ <span class="ident">spc</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="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
491
+ <span class="punct">...</span>
492
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
493
+
494
+
428
495
  <p>If you prefer the <code>define</code> approach to registering services, you may like <code>namespace_define</code>, which creates the new namespace and immediately calls <code>define</code> on it:</p>
429
496
 
430
497
 
431
- <pre>
432
- registry.namespace_define :stuff do |b|
433
- b.foo { Bar.new }
434
- ...
435
- end
436
- </pre>
498
+ <div class='figure'>
499
+ <span class='caption'>Creating namespaces with #namespace_define [ruby]</span>
500
+ <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">registry</span><span class="punct">.</span><span class="ident">namespace_define</span> <span class="symbol">:stuff</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
501
+ <span class="ident">b</span><span class="punct">.</span><span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
502
+ <span class="punct">...</span>
503
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
504
+
505
+
437
506
  <p>And, to mirror the <code>namespace_define</code> method, there is also a <code>namespace_define!</code> method. This method creates a new namespace and then does a <code>define!</code> call on that namespace.</p>
438
507
 
439
508
 
440
- <pre>
441
- registry.namespace_define! :stuff do
442
- foo { Bar.new }
443
- ...
444
- end
445
- </pre>
509
+ <div class='figure'>
510
+ <span class='caption'>Creating namespaces with #namespace_define! [ruby]</span>
511
+ <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">registry</span><span class="punct">.</span><span class="ident">namespace_define!</span> <span class="symbol">:stuff</span> <span class="keyword">do</span>
512
+ <span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
513
+ <span class="punct">...</span>
514
+ <span class="keyword">end</span></pre></div></td></tr></table></div></div>
515
+
516
+
446
517
  <p>The above code would create a new namespace called <code>:stuff</code> in the registry, and would then proceed to register a service called <code>:foo</code> in the new namespace.</p>
447
518
  </div>
448
519
 
449
520
 
450
521
 
522
+ <div class="bottom"><div class="prevnext">
523
+
524
+ <a href="chapter-1.html">Previous (1. Introduction)</a> |
525
+
526
+ <a href="index.html">Up</a>
527
+
528
+ | <a href="chapter-3.html">Next (3. Service Locator)</a>
529
+
530
+ </div></div>
531
+
451
532
 
452
533
  </div>
453
534