Service Resolution

Once you've registered, validated, and instantiated a ServiceProvider, you'll eventually need to get something out of it. This should typically only happen at the root of your application, but it might occur in other scenarios such as creating a new scope. The following functions are provided to resolve services:

FunctionResolution
getA single service, if it's registered
get_mutA single, mutable service, if it's registered
get_by_keyA single service by key, if it's registered
get_by_key_mutA single, mutable service by key, if it's registered
get_allAll services of the specified type
get_all_mutAll mutable services of the specified type
get_all_by_keyAll services of the specified type and key
get_all_by_key_mutAll mutable services of the specified type and key
get_requiredA single service or panics
get_required_mutA single, mutable service or panics
get_required_by_keyA single service by key or panics
get_required_by_key_mutA single, mutable service by key or panics

Examples

Consider the following structures:

use di::*;

trait Thing { }

struct Thing1;

impl Thing for Thing1 { }

struct Thing2;

impl Thing for Thing2 { }

struct Thing3;

impl Thing for Thing3 { }

Here are some ways that we can register and resolve them:

use crate::*;
use di::*;

let provider = ServiceCollection::new()
    .add(transient_as_self::<Thing1>().from(|_| Ref::new(Thing1)))
    .add(transient::<dyn Thing, Thing1>().from(|_| Ref::new(Thing1)))
    .add(transient::<dyn Thing, Thing2>().from(|_| Ref::new(Thing2)))
    .add(transient_mut::<dyn Thing, Thing3>().from(|_| RefMut::new(Thing3.into())))
    .build_provider()
    .unwrap();

// Some(Thing1)
assert!(provider.get::<Thing1>().is_some());

// None
assert!(provider.get::<Thing3>().is_none());

// RwLock<dyn Thing> → RwLock<Thing3>
assert!(provider.get_mut::<dyn Thing>().is_some());

// dyn Thing → Thing1
// dyn Thing → Thing2
assert_eq!(provider.get_all::<dyn Thing>().count(), 2);