<html> <head> <title>Needle Manual :: Chapter 2: Registry</title> <link type="text/css" rel="stylesheet" href="manual.css" /> </head> <body> <div id="banner"> <table border='0' cellpadding='0' cellspacing='0' width='100%'> <tr><td valign='top' align='left'> <div class="title"> <span class="product">Needle—</span><br /> <span class="tagline">to the point --></span> </div> </td><td valign='middle' align='right'> <div class="info"> Needle Version: <strong>0.5.0</strong><br /> Manual Last Updated: <strong>2004-10-15 03:41 GMT</strong> </div> </td></tr> </table> </div> <table border='0' width='100%' cellpadding='0' cellspacing='0'> <tr><td valign='top'> <div id="navigation"> <h1>Needle Manual</h1> <h2>Chapters</h2> <ol type="I"> <li> <a href="chapter-1.html"> Introduction </a> <ol type="1"> <li><a href="chapter-1.html#s1">What is Needle?</a></li> <li><a href="chapter-1.html#s2">How Can It Help Me?</a></li> <li><a href="chapter-1.html#s3">License Information</a></li> <li><a href="chapter-1.html#s4">Support</a></li> </ol> </li> <li><strong> <a href="chapter-2.html"> Registry </a> </strong> <big>←</big> <ol type="1"> <li><a href="chapter-2.html#s1">Overview</a></li> <li><a href="chapter-2.html#s2">Creating</a></li> <li><a href="chapter-2.html#s3">Services</a></li> <li><a href="chapter-2.html#s4">Namespaces</a></li> </ol> </li> <li> <a href="chapter-3.html"> Dependency Injection </a> <ol type="1"> </ol> </li> <li> <a href="chapter-4.html"> Interceptors </a> <ol type="1"> </ol> </li> <li> <a href="chapter-5.html"> Service Models </a> <ol type="1"> </ol> </li> <li> <a href="chapter-6.html"> Logging </a> <ol type="1"> </ol> </li> <li> <a href="chapter-7.html"> Creating Libraries </a> <ol type="1"> </ol> </li> </ol> <h2>API Reference</h2> <ul> <li><a href="http://needle.rubyforge.org/api/index.html">Needle API</a></li> </ul> <h2>Tutorials</h2> <ol> </ol> <p align="center"><strong>More To Come...</strong></p> <div class="license"> <a href="http://creativecommons.org/licenses/by-sa/2.0/"><img alt="Creative Commons License" border="0" src="http://creativecommons.org/images/public/somerights" /></a><br /> This manual is licensed under a <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons License</a>. </div> </div> </td><td valign='top' width="100%"> <div id="content"> <h1>2. Registry</h1> <h2> <a name="s1"></a> 2.1. Overview </h2> <div class="section"> <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> <p>In order to use Needle, you only really <em>need</em> to understand how to create and manipulate registry objects.<br /> </p> </div> <h2> <a name="s2"></a> 2.2. Creating </h2> <div class="section"> <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> <pre> require 'needle' registry = Needle::Registry.new </pre> <p>Once you have the reference to the registry, you can register services with it, create new namespaces in it, and so forth.<br /> </p> </div> <h2> <a name="s3"></a> 2.3. Services </h2> <div class="section"> <p>Registering services with a Needle registry is very straightforward. The simplest way to do it is:</p> <pre> registry.register( :foo ) { Bar.new } </pre> <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> <p>You get services from the registry in either of two ways:</p> <pre> # Treating the registry as a Hash svc = registry[:foo] # Treating the service as a property of the registry svc = registry.foo </pre> <h3>Convenience Methods</h3> <p>Because you will often need to register many services with a registry at once, a convenience method has been provided to make this use case lean and mean. Just call <code>registry!</code>, passing a block that accepts no parameters. This block will be evaluated in a new context, with any unrecognized method call being interpreted as a new service registration of that name:</p> <pre> registry.register! do foo { Bar.new } bar { Foo.new } ... end </pre> <p>The above will register two new services with the registry, <code>:foo</code> and <code>:bar</code>.</p> <h3>Default Lifecycle</h3> <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> <pre> svc1 = registry.foo svc2 = registry.foo p svc1.object_id == svc2.object_id #=> true </pre> <p>You can change this behavior, with <em>service models</em>. See the chapter on Service Models for more information.<br /> </p> </div> <h2> <a name="s4"></a> 2.4. Namespaces </h2> <div class="section"> <p>Namespaces allow you to organize your services. The feature has many different applications, including:</p> <ol> <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> <li>Developers may organize complex applications into modules, and the service definitions may be stored in the registry to reflect that organization.</li> <li>Services deeper in the hierarchy may override services higher up.</li> </ol> <p>Creating a namespace is as easy as invoking the <code>#namespace</code> method of the registry (or of another namespace):</p> <pre> registry.namespace :stuff </pre> <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> <pre> registry.stuff.register( :foo ) { Bar.new } ... svc = registry.stuff.foo </pre> <p>Here’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> <pre> svc = registry[:stuff][:foo] </pre> <h3>Convenience Methods</h3> <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> <pre> registry.namespace :stuff do |spc| spc.register( :foo ) { Bar.new } ... end </pre> <p>And, to mirror the <code>register!</code> method, there is also a <code>namespace!</code> method. This method creates a new namespace and then does a <code>register!</code> call on that namespace.</p> <pre> registry.namespace! :stuff do foo { Bar.new } ... end </pre> <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> </div> </div> </td></tr> </table> </body> </html>