I recently created
Gimme, a small ruby gem which allows you to configure and access a simple
Registry using a nice little DSL.
Gimme in a paragraph
The general idea of Gimme is to allow a single point for configuring the well known services which your application uses (think DB connection, twitter API gateway, email server, etc). Once configured Gimme then exposes a single point to access those services, without needing to resort to singletons or global variables.
Show me teh codez
Here's a simple example showing how you would configure your registry:
Gimme.configure |g|
g.for_the(ExternalService) do |env,name|
ExternalService.new(env[:setting1],env[:setting2])
end
end
and here's how you'd use it from within your app:
Gimme.the(ExternalService).some_method
Here's a more complete example, showing both configuration and usage:
# your Emailer class
class Emailer
def initialize( smtp_hostname, port )
@smtp_hostname, @port = smtp_hostname, port
puts "creating an emailer: #{inspect}"
end
def send_email( subject )
puts "Sending email '#{subject}' via #{inspect}"
# ...
end
def inspect
"#{@smtp_hostname}:#{@port}"
end
end
# your Gimme configuration
Gimme.configure do |g|
g.for_the( Emailer ) do |env|
email_settings = env[:email_settings]
Emailer.new(email_settings[:hostname],email_settings[:port])
end
end
Gimme.environment = {:email_settings => {:hostname => 'smtp.mymailserver.com', :port => '2525'} }
# in your app
Gimme.the(Emailer).send_email( "Gimme is the awesomez" )
Gimme.the(Emailer).send_email( "Emailing is fun" )
Gimme.the(Emailer).send_email( "notice that only one Emailer was created above" )
Gimme.the(Emailer).send_email( "even though we sent 4 emails" )
Pseudo-singletons
If you use the Gimme#for_the(Service) form when configuring Gimme then gimme will only create one instance of that object. If you use the Gimme#for_a(Service) form then the creation block will be called each time you ask for an instance of that object. That way things which hold on to expensive resources (database connections, TCP sockets) can be shared within your app, which services which need to maintain unique state for each client can be private to each client.
Environments
In any non-trivial application you need to configure your services. You can supply Gimme with an environment hash which it will then pass to your creation blocks whenever you ask for an object. This allows you to store settings like smtp hostnames, database passwords, twitter API keys, etc in a single environment hash, and use that hash in one place to configure all your external services at the point they are created.
Dependency Injection/IoC
There is nothing to stop you from calling Gimme.a() or Gimme.the() from within a creation block. This allows you to use Gimme as a lightweight IoC container.
Check it out!
Check out
the github page for more info, including lots of example usages, and a more detailed README.
No comments:
Post a Comment