Created
February 17, 2012 15:36
-
-
Save mullr/1854059 to your computer and use it in GitHub Desktop.
jinja.coffee: a minuscule DI container for javascript/coffeescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# jinja.coffee: a minuscule DI container for javascript/coffeescript | |
# | |
# Put your class dependencies under meta.needs and needs_modules, and | |
# you'll get a hash of whan you asked for as a constructor parameter. A | |
# useful idiom is to stash the whole thing in a property named 'd', | |
# for dependencies. | |
# | |
# class A | |
# @meta: | |
# needs: ["someParam"] | |
# needsModules: ["request", "fs"] | |
# | |
# constructor: (@d) -> | |
# | |
# doSomething: -> | |
# @d.fs.readFile ... | |
# | |
# c = new jinja.Container | |
# c.register "someParam", "foo" | |
# c.register "a", A | |
# | |
# a = c.resolve "a" | |
module.exports.Container = class Container | |
registry = {} | |
register: (key, impl) -> | |
registry[key] = impl | |
registerModule: (key, module) -> | |
registry[key] = require(module) | |
resolve: (key) -> | |
throw "nothing registered for key: #{key}" unless registry.hasOwnProperty(key) | |
impl = registry[key] | |
# any objects or strings or numbers just get returned | |
return impl unless typeof(impl) is 'function' | |
# With a function, see if we have an metadata about it | |
args = {} | |
if impl.meta?.needs? | |
args[k] = @resolve(k) for k in impl.meta.needs | |
if impl.meta?.needsModules? | |
args[k] = require(k) for k in impl.meta.needsModules | |
return new impl(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jinja = require("./jinja.coffee") | |
class A | |
@meta: { needs: ["param"] } | |
constructor: (@d) -> | |
getParam: -> @d.param | |
class B | |
@meta: { needs: ["param", "a"] } | |
constructor: (@d) -> | |
getParam: -> @d.param | |
getA: -> @d.a | |
class NeedsModule | |
@meta: { needsModules: ["http"] } | |
constructor: (@d) -> | |
getHttp: -> @d.http | |
describe "jinja:", -> | |
describe "Container:", -> | |
c = new jinja.Container() | |
it "can register value types", -> | |
c.register("param", "foo") | |
c.register("a", A) | |
a = c.resolve("a") | |
expect(a.getParam()).toBe("foo") | |
it "can register class", -> | |
c.register "param", "foo" | |
c.register "a", A | |
c.register "b", B | |
b = c.resolve("b") | |
expect(b.getA()).not.toBeNull() | |
expect(b.getA().getParam()).toBe("foo") | |
expect(b.getParam()).toBe("foo") | |
it "can provide module references", -> | |
c.register "nm", NeedsModule | |
nm = c.resolve "nm" | |
expect(nm.getHttp()).toBeDefined() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment