Inject
Zova injects Bean instances through @Use
decorator function
Resolution rules
Zova adopts a modular system, and Bean Classes are provided by different modules. When using the Bean Class inside the same module, you can directly resolve it based on Class type
. When using cross-module, you can resolve it based on Bean identifier
instead of Class type/file path
, which is conducive to achieving loose coupling between modules
Therefore, Zova provides the following resolution rules:
- Bean Class
- Bean identifier
- Registration name
- Variable name
1. Bean Class
Use Bean Class
to lookup and inject bean instance in the ioc container, and automatically create one if not exist. This mechanism is generally used for same module injection
import { ModelTodo } from '../../bean/model.todo.js';
class ControllerTodo {
@Use()
$$modelTodo: ModelTodo;
}
2. Bean identifier
Use Bean identifier
to lookup and inject bean instance in the ioc container, and automatically create one if not exist. This mechanism is generally used for cross-module injection
and hierarchical injection
import type { ModelTabs } from 'zova-module-a-tabs';
class ControllerLayout {
@Use('a-tabs.model.tabs')
$$modelTabs: ModelTabs;
}
- Lookup and inject bean instance through
a-tabs.model.tabs
- Therefore, only the type of ModelTabs needs to be imported to maintain the loose coupling relationship between modules
In order to simplify the code, we can still use the Class-type-based
code style. Based on the support of the compiler, this Class-type-based
code style will automatically be converted to the Bean-identifier-based
code style. Then the optimized code style is as follows:
import { ModelTabs } from 'zova-module-a-tabs';
class ControllerLayout {
@Use()
$$modelTabs: ModelTabs;
}
- See: Bean Identifier
3. Registration name
Lookup and inject bean instance in the ioc container through the registration name
, and return a null value if not exist. This mechanism is generally used for same module injection
and hierarchical injection
import { ModelTodo } from '../../bean/model.todo.js';
class ControllerTodo {
@Use({ name: '$$modelTodo' })
$$modelTodo: ModelTodo;
}
- Lookup and inject the bean instance by the registration name
$$modelTodo
. Generally speaking, you should ensure that the bean instance has been injected in the ioc container in advance, otherwise a null value will be returned
4. Variable name
Lookup and inject the bean instance in the ioc container by the variable name
, and return a null value if not exist. This mechanism is generally used for same module injection
and hierarchical injection
import type { ModelTodo } from '../../bean/model.todo.js';
class ControllerTodo {
@Use()
$$modelTodo: ModelTodo;
}
- Lookup and inject the bean instance by the variable name
$$modelTodo
. Generally speaking, you should ensure that the Bean instance has been injected in the ioc container in advance, otherwise a null value will be returned
Injection scope
The default injection scope of anonymous bean
is ctx
, and the default injection scope of named bean
can be specified when defining it. Different scenes have different default injection scopes. In addition, when injecting, you can also override the default injection scope through the injectionScope
option in @Use
Zova provides the following injection scopes: app/ctx/new/host/skipSelf
1. app
If the injection scope is app
, then inject the bean instance in the global ioc container to achieve the singleton effect
// in module: test-module1
@Store()
class StoreCounter {}
// in module: test-module2
import { StoreCounter } from 'zova-module-test-module1';
class Test {
@Use()
$$storeCounter: StoreCounter;
}
- The injection scope of
Store
isapp
by default, so the bean instance will be lookuped and injected in the global ioc container
2. ctx
If the injection scope is ctx
, then inject the bean instance into the ioc container of the current component instance
// in module: a-tabs
@Model()
class ModelTabs {}
// in module: test-module2
import { ModelTabs } from 'zova-module-a-tabs';
class ControllerLayout {
@Use()
$$modelTabs: ModelTabs;
}
- The injection scope of
Model
isctx
by default, so the bean instance will be lookuped and injected in the ioc container of the current component instance
3. new
If the injection scope is new
, then directly create a new bean instance
// in module: a-tabs
@Model()
class ModelTabs {}
// in module: test-module2
import { ModelTabs } from 'zova-module-a-tabs';
class ControllerLayout {
@Use({ injectionScope: 'new' })
$$modelTabs: ModelTabs;
}
- Since the
injectionScope
option is specified asnew
, a new bean instance will be directly created
Hierarchical injection
Injection scope supports not only app/ctx/new
, but also host/skipSelf
which is called hierarchical injection
4. host
If the injection scope is host
, the bean instance will be lookuped in the ioc container of the current component instance and all parent containers in turn. If it does not exist, a null value is returned
// in parent component
import { ModelTabs } from 'zova-module-a-tabs';
class Parent {
@Use()
$$modelTabs: ModelTabs;
}
// in child component
import type { ModelTabs } from 'zova-module-a-tabs';
class Child {
@Use({ injectionScope: 'host' })
$$modelTabs: ModelTabs;
}
- Since the parent component has already injected the
ModelTabs
bean instance, the child component can directly lookup and inject it Hierarchical injection
also supports all resolution rules
5. skipSelf
If the injection scope is skipSelf
, then lookup the bean instance in all parent containers in turn. If it does not exist, a null value is returned