sergiolepore / Cation

A fast and customizable Dependency Injection Container for Node.js / io.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

parent container?

stephanos opened this issue · comments

I'm working on an app that consists of multiple modules. Now I want to have a shared kernel, a set of resources that can be used across the modules.

One such resource is Config. It reads the config/ directory and provides an interface to read config keys: get(key, namespace). There are global config values which are in the namespace 'global', and each module can specify its own under its according namespace. The get method tries to find a non-global value for the provided namespace first, and if it didn't find anything it returns the global value (or throws an error if both weren't found).

With the current state of Cation I would register Config and then declare it as a dependency in any module's resource that requires it. So far so good. But now these resources would need to know in what module they are residing in order to specify the correct namespace value to fetch the config values.

It would be great if I could have a root Cation container and a module-specific one. This way, I could have a root Config resource (which actually reads and parses the config files) and a module-specific Config resource (which is just a thin wrapper around the global one but with a default namespace value).

It would be cool if I could have a hierarchy of Cation containers: When a container doesn't find what is required, it asks its parents.

Do you think that makes sense?
Is there a workaround I could use to achieve this?

Hmm... I've already tried to implement a Parent-Sub container feature, but then I rolled everything back (see this branch).
Then I decided to go for a less "painful" modification, which is the current "tag" feature.

In your specific case, the module-specific Config resources are different objects? Because maybe, maybe, you can try tagging those resources and asking Cation for them.

var ids = container.findTaggedResourceIds('submodule:config')

Let me know if you have any further questions 😄

Thanks for the response!

Sub-containers can really be a dangerous feature and destroy the simplicity of your project if done wrong. So I wouldn't consider adding it unless absolutely necessary.

I looked at the tag feature, but I don't think it will work in my use case. Let me flesh out the example a bit more:

For the sake of simplicity, let's assume I have two modules: kernel and app. The kernel has a resource that reads and parses the config files (BaseConfig). And the app has a thin wrapper around it that adds the correct namespace to each config value request (Config). Now I have a reusable resource in the kernel that wants to know the markup-specific settings (e.g. remove whitespace?).

Here is a little illustration:

kernel |  [BaseConfig]     [TemplateEngine]
             ^                      |
-------------|----------------------|---------
             |                      |
app    |   [Config]   <-------------|

The problem is that TemplateEngine is defined in the kernel (since it's reusable) but is executed in the app module. It must be since it wants to take the app module's specific settings into account. But it can't know in which module it will run, so namespacing the requirements won't work.

I could create module-specific wrappers that just connect all the parts between modules, but that would defeat the purpose of having a autowiring container.

Anyway, what I think might work with the current code is to add 'references' of a parent container to a module-specific container. And have a custom resolver for these references that ask the parent container for a promise. I'll try to implement this today.

After fiddling around a bit with this I think it's too much effort to make it work like this.

I'm now considering to just have a TemplateEngineFactory which can be injected and then creates a TemplateEngine. This is totally doable with Cation.

You can find my implementation here (note: I'm using my own API wrapper around Cation and use decorators to annotate resources).

You can close this if you don't want to pursue this any further.

Hey, that's awesome!
I have no plans for the subcontainer functionality anytime soon, but I'll let you know if I decide to resurrect the feature.

Great, thanks!