![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
TameTheBeast lets you define the creation of components of your application in a central container. It is inspired by this blog post by Jim Weirich.
A central singleton is eventually inevitable for any application, but if you are like me, it tends to suck up and swallow functionality that really should be separate from each other. You end up with one big blob of unmanageable spaghetti since everything is tightly coupled.
Dependency injection is a way out that has proven to be effective in OOP. TameTheBeast aims at giving some nice lightweight sugar above it. (What it actually does is it patronizes you. Have been warned.)
container = TameTheBease.new
container.register(:app_state) do
{ :running => false, :initializing => true }
end
container.register(:splash_window, :using => :app_state) do |h|
SplashWindow.new(h.app_state)
end
# ...many more components registered here...
resolution = container.resolve(:for => [:splash_window, ...])
# => { :splash_window => <SplashWindow...> }
So this is the pattern:
Explicitly declaring your dependencies in this way really helps in refactoring later!
Access the resolution and the inject hashes by []
or by name.
That means you can say resolution[:app_state]
as well as resolution.app_state
. Same for the inject hashes.
There are three ways to accomplish that:
container.resolve_for :configuration, :app_state
# or, at register time
container.register(:printer_dialog, :resolve => true)
# or, at resolution time
container.resolve(:for => [:configuration, :app_state])
All components mentioned in any of the three ways will get resolved for. Call resolve_for
as often as you like.
Slots have to be symbols, but when declaring dependencies or resolving, you can reference them as strings like this:
container.register(:foo, :using => %w{bar baz}) { ... }
container.resolve_for %w{foo bar baz}
Is this really sugar? Not sure. Anyway, you can leave off the block on register
,
and the component will be initialized as a stub. This way you can play around with the effects of
refactorings on dependencies to some extent without having to go too deep.
The stub will yell at you when you try to use it.
Just ask.
container.complete?
container.free_of_loops?
If there are dependency loops, resolve
will raise an exception.
Nothing fancy yet, but you can do
container.render_dependencies(:format => :hash)
# => { :splash_window => [:app_state], ... }
Let me know if you know of a way to visualize this easily!
I have not yet completely made up my mind about this yet, but it seems like it is not always possible to avoid circular dependencies. You can break them up and post-inject like this:
container.register(:component) do |h|
...
end.post_inject_into { |h| h.parent = h.root_something } # or similar foo
The post injection block will be called right before the resolution is returned. It is passed the resolution.
If you think you need this feature, really think hard if you cannot find a way around (I believe there usually is). Using this feature should actually give you some pain, but I could not find a reliable way to implement this.
There is no such thing as incremental resolution, you cannot use a component directly while still registering construction of others.
However, you can break up the registration into multiple phases and simply inject the result of prior resolve
runs:
container.inject(resolution_from_the_past)
If you have existing objects, you can actually keep them in a hash and inject them in this way. There is nothing special about using a resolve
result here!
Released under the MIT License. See the LICENSE file for further details.
FAQs
Unknown package
We found that tame_the_beast demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.