Struct runtime_injector::Injector [−][src]
pub struct Injector { /* fields omitted */ }
Expand description
A runtime dependency injection container. This holds all the bindings between service types and their providers, as well as all the mappings from interfaces to their implementations (if they differ).
Injecting the injector
Cloning the injector does not clone the providers inside of it. Instead, both injectors will use the same providers, meaning that an injector can be passed to a service as a dependency. The injector can be requested as itself without using a service pointer. It does not need to be registered as a dependency in the builder beforehand.
Note that requesting the injector inside of your services is generally bad
practice, and is known as the service locator antipattern. This is mostly
useful for custom ad-hoc service factories where you can create instances
of your services on demand. If you need to create instances of a service
outside of your constructor, you may want to use Factory<R>
instead.
use runtime_injector::{ constant, InjectResult, Injector, IntoSingleton, IntoTransient, Svc, }; use std::sync::Mutex; struct FloatFactory(Injector); impl FloatFactory { pub fn get(&self) -> InjectResult<f32> { let int: Box<i32> = self.0.get()?; Ok(*int as f32) } } fn count(counter: Svc<Mutex<i32>>) -> i32 { let mut counter = counter.lock().unwrap(); *counter += 1; *counter } let mut builder = Injector::builder(); builder.provide(constant(Mutex::new(0i32))); builder.provide(count.transient()); builder.provide(FloatFactory.singleton()); let injector = builder.build(); let float_factory: Svc<FloatFactory> = injector.get().unwrap(); let value1 = float_factory.get().unwrap(); let value2 = float_factory.get().unwrap(); assert_eq!(1.0, value1); assert_eq!(2.0, value2);
Implementations
impl Injector
[src]
impl Injector
[src]#[must_use]pub fn builder() -> InjectorBuilder
[src]
#[must_use]pub fn builder() -> InjectorBuilder
[src]Creates a builder for an injector. This is the preferred way of creating an injector.
#[must_use]pub fn new(
providers: HashMap<ServiceInfo, Option<Vec<Box<dyn Provider>>>>
) -> Self
[src]
👎 Deprecated since 0.3.1: prefer using a builder; this will be removed in 0.5
#[must_use]pub fn new(
providers: HashMap<ServiceInfo, Option<Vec<Box<dyn Provider>>>>
) -> Self
[src]prefer using a builder; this will be removed in 0.5
Creates a new injector directly from its providers and implementations.
Prefer Injector::builder()
for creating new injectors instead.
pub fn get<R: Request>(&self) -> InjectResult<R>
[src]
pub fn get<R: Request>(&self) -> InjectResult<R>
[src]Performs a request for a service. There are several types of requests that can be made to the service container by default:
Svc<T>
: Requests a service pointer to the given interface and creates an instance of the service if needed. If multiple service providers are registered for that interface, then returns an error instead.Box<T>
: Requests an owned service pointer to the given interface and creates an instance of the service. Not all service providers can provide owned versions of their services, so this may fail for some services.Option<Svc<T>>
/Option<Box<T>>
: Requests a service pointer to the given interface and creates an instance of the service if needed. If no provider for that service is registered, then returnsOk(None)
rather than returning an error. If multiple providers are registered, then instead returns an error. If an owned pointer is requested but the provider can’t provide owned pointers, then returns an error.Vec<Svc<T>>
/Vec<Box<T>>
: Requests all the implementations of an interface. This will eagerly create the services as part of the request. If owned service pointers are requested and any providers can’t provide owned pointers, then returns an error instead.Services<T>
: Requests all the implementations of an interface. This will lazily create the services on demand. See the documentation forServices<T>
for more details.Injector
: Requests a clone of the injector. While it doesn’t make much sense to request this directly from the injector itself, this allows the injector to be requested as a dependency inside of services (for instance, factories).RequestInfo
: Requests information about the current request, including the current resolution path.Factory<R>
: Lazily performs requests on demand.
See the documentation for Request
for more information on
what can be requested. Custom request types can also be created by
implementing Request
on your type.
Requests to service pointers of sized types will attempt to use the registered provider to retrieve an instance of that service. For instance, a request for a singleton service will create an instance of that service if one doesn’t exist already, and either return a service pointer to the instance that was already created, or return a service pointer to the new instance (if one didn’t exist already).
use runtime_injector::{Injector, IntoSingleton, Svc}; #[derive(Default)] struct Bar; let mut builder = Injector::builder(); builder.provide(Bar::default.singleton()); let injector = builder.build(); let _bar: Svc<Bar> = injector.get().unwrap();
Requests for service pointers of dyn Trait
interface types will
instead request the implementation of that interface type. For example,
if dyn Foo
’s registered implementation is for the service type Bar
,
then a request for a service pointer of dyn Foo
will return a service
pointer to a Bar
, although the return type will be Svc<dyn Foo>
.
use runtime_injector::{ interface, Injector, IntoSingleton, Svc, TypedProvider, }; trait Foo: Send + Sync {} interface!(dyn Foo = [Bar]); #[derive(Default)] struct Bar; impl Foo for Bar {} let mut builder = Injector::builder(); builder.provide(Bar::default.singleton().with_interface::<dyn Foo>()); let injector = builder.build(); let _bar: Svc<dyn Foo> = injector.get().unwrap();
If multiple providers for a service exist, then a request for a single service pointer to that service will fail.
use runtime_injector::{ interface, Injector, IntoSingleton, Svc, TypedProvider, }; trait Foo: Send + Sync {} interface!(dyn Foo = [Bar, Baz]); #[derive(Default)] struct Bar; impl Foo for Bar {} #[derive(Default)] struct Baz; impl Foo for Baz {} let mut builder = Injector::builder(); builder.provide(Bar::default.singleton().with_interface::<dyn Foo>()); builder.provide(Baz::default.singleton().with_interface::<dyn Foo>()); let injector = builder.build(); assert!(injector.get::<Svc<dyn Foo>>().is_err());
pub fn get_with<R: Request>(
&self,
request_info: &RequestInfo
) -> InjectResult<R>
[src]
pub fn get_with<R: Request>(
&self,
request_info: &RequestInfo
) -> InjectResult<R>
[src]Performs a request for a service with additional request information.
Example
use runtime_injector::{ Injector, IntoTransient, Request, RequestInfo, Svc, }; struct Foo(String); impl Foo { fn new(request_info: RequestInfo) -> Self { let value = request_info .get_parameter("value") .unwrap() .downcast_ref::<String>() .unwrap() .clone(); Foo(value) } } let mut builder = Injector::builder(); builder.provide(Foo::new.transient()); let injector = builder.build(); let mut request_info = RequestInfo::default(); request_info.insert_parameter("value", "foo".to_owned()); let foo: Svc<Foo> = injector.get_with(&request_info).unwrap(); assert_eq!("foo", foo.0);
Trait Implementations
impl Request for Injector
[src]
impl Request for Injector
[src]Requests the injector used to resolve services.
fn request(injector: &Injector, _info: &RequestInfo) -> InjectResult<Self>
[src]
fn request(injector: &Injector, _info: &RequestInfo) -> InjectResult<Self>
[src]Performs the request to the injector.
Auto Trait Implementations
impl !RefUnwindSafe for Injector
impl Send for Injector
impl Sync for Injector
impl Unpin for Injector
impl !UnwindSafe for Injector
Blanket Implementations
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]pub fn borrow_mut(&mut self) -> &mut T
[src]
pub fn borrow_mut(&mut self) -> &mut T
[src]Mutably borrows from an owned value. Read more
impl<T> ToOwned for T where
T: Clone,
[src]
impl<T> ToOwned for T where
T: Clone,
[src]type Owned = T
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn to_owned(&self) -> T
[src]Creates owned data from borrowed data, usually by cloning. Read more
pub fn clone_into(&self, target: &mut T)
[src]
pub fn clone_into(&self, target: &mut T)
[src]🔬 This is a nightly-only experimental API. (toowned_clone_into
)
recently added
Uses borrowed data to replace owned data, usually by cloning. Read more