Standalone Mode and Component Decorators

The standalone mode is designed to allow developers to quickly use the Imagination container with any programming frameworks.

To use this, instead of using imagination.assembler.core.Assembler in Basic Setup, you can just simply call.

from imagination.standalone import container

where container is an instance of imagination.core.Imagination.

Imagination in the standalone mode only is currently designed to loaded configuration files from the configuration file from (this the listed order):

  • Wherever you define in the system environment variable IMAGINATION_CONF_FILEPATH
  • imagination.xml (from the current working directory)
  • services.xml (from the current working directory)
  • service decorators (see the next section)

Note

You can also load more configuration files later by calling :method:`imagination.standalone.load_config_file`.

Decorator API

With the feedback from the community, in version 3.3, you can use decorators to configure services without the need to learn how to write XML. This feature is now generally available for testing based on the rolling feature ticket.

Note

It currently only supports entity-type service declarations.

How to use the API

The decorator API will use a different set of terminologies, but similar to Angular’s.

The decorator imagination.decorator.Component is to declare an entity-type service where the constructor’s arguments (AKA parameters) can be defined with the following object of these classes.

  • imagination.decorator.config.Parameter is a primitive-type argument.
    • It is equivalent to <param/> for primitive-type arguments but without type attribute as the type is inferred from the value.
  • imagination.decorator.config.Service is an injectable argument for components.
    • If you have an argument with type hint to a class, which is declared as a component, you can leave this blank as the container will automatically figure out which component to use by type hint.
  • imagination.decorator.config.EnvironmentVariable is an argument whose value is derived from an environment variable.

Example

Suppose we have Service1 with no parameters.

from imagination.decorator import service

@service.registered()
class Service1:
    ...

Instead of registering in an XML file, we now can use @service.registered() to declare this as a (singleton) service.

Let’s say we also have Service2 that requires Service1.

from imagination.decorator.config import Parameter, Service

from app.service import Service1

@service.registered([
    Parameter('Panda'),
    Service(Service1),
])
class Service2:
    def __init__(self, name: str, s1: Service1):
        ...

But this is still mouthful to declare a service. You can simplify this by leaving Service alone.

@service.registered([Parameter('Panda')])
class Service2:
    def __init__(self, name: str, s1: Service1):
        ...

To call components, you can simply use imagination.standalone.container.

from imagination.standalone import container
from app.service.s1 import Service1
from app.service.s2 import Service2

s1 : Service1 = container.get(Service1)  # --> Service1
s2 : Service2 = container.get(Service2)  # --> Service2