Dependency injection for Rust
How to use:
Cargo.toml
:
= "1.6.5"
lib.rs
or any other file, that uses library:
use *;
See examples/1_get_started.rs for minimal example of usage.
See examples/2_modules.rs for example with modules and constructors.
See examples/3_inject_options_list.rs for the demo of all available injection options.
How to use
Annotate structure with #[component]
Annotate impl blocks with #[provides]
Create a container:
Get dependency ref:
Inject references
For Rc:
;
to use Arc
instead of Rc
you need to add async
feature in cargo:
= { = "...", = [ "async" ] }
Also, you can use waiter_di::Wrc
type that will be compiled to Rc
or Arc
depending on async
feature.
To create new struct instead of getting reference:
Properties
It uses config
crate under the hood, for example it tries to find float_prop
in args as --float_prop <value>
, if not found it tries to find it in environment variables,
after that tries config/{profile}.toml
, after that config/default.toml
Dependency cycle
Use Deferred type:
Profiles
You can use predefined profiles from `waiter_di::profile" or create custom:
;
Get profile from args, environment or config/default.toml
Just define property named profile
as --profile <profile>
arg, profile
env variable or
profile
property in config/default.toml
and use inject!
macro:
inject!
macro can't be used for several components, so it's recommended to use it with modules:
In this case #[module]
is just a synonym for #[component]
Factory functions:
If you can't use #[component]
annotation, use factory function instead:
To use it like a constructor, use it with #[component]
on impl block:
;
Deferred
args in factory functions is unsupported. In the rest it can accept
the same arg types as #[component]
.
External types isn't supported for factory functions:
// won't compile
So you need to create crate-local wrapper:
;
For convenience, you can use #[wrapper]
attribute to implement Deref automatically:
;