Struct he_di::ContainerBuilder [] [src]

pub struct ContainerBuilder { /* fields omitted */ }

Build a Container registering components with or without parameters.

Once finished, you have to call build() to build the associated Container. This method can Err if you tried to register invalid values.

See module documentation or ContainerBuilder::build() for more details.

Methods

impl ContainerBuilder
[src]

Create a new ContainerBuilder.

Same as register(), for backward compatibility.

Register a new component with this builder. If that component was already registered, the old Component is replaced (same as HashMap.insert() except we don't return the old Component).

This method returns a mutable RegisteredType allowing to chain calls to:

  1. as_type(): to set the interface this Component implements,
  2. with_named_parameter() or with_typed_parameter(): to add parameters to be used to instantiate this Component.

To be properly registered, as_type() must be called before calling ContainerBuilder::build(), if not, execution will Err.

Parse this ContainerBuilder content to check if all the registrations are valid. If so, consume this ContainerBuilder to build a Container.

Errors

A he_di::Error::RegistrationError can be returned when trying to build an invalid ContainerBuilder containing:

Examples

extern crate he_di;
#[macro_use] extern crate he_di_derive;
 
use he_di::Error as DIError;
use he_di::container::ValidatorError;
 
trait Foo { fn foo(&self); }
trait FooInvalid { fn foo(&self); }
trait FooDuplicate { fn foo(&self); }
 
#[derive(Component)]
#[interface(Foo)]
struct FooImpl;
 
#[derive(Component)]
#[interface(FooInvalid)]
struct FooInvalidImpl;
 
#[derive(Component)]
#[interface(FooDuplicate)]
struct FooDuplicateImpl1;
 
#[derive(Component)]
#[interface(FooDuplicate)]
struct FooDuplicateImpl2;
 
impl Foo for FooImpl { fn foo(&self) { } }
impl FooInvalid for FooInvalidImpl { fn foo(&self) { } }
impl FooDuplicate for FooDuplicateImpl1 { fn foo(&self) { } }
impl FooDuplicate for FooDuplicateImpl2 { fn foo(&self) { } }
 
fn main() {
    let mut builder = he_di::ContainerBuilder::new();

    // Valid registration
    builder.register::<FooImpl>()
        .as_type::<Foo>();
 
    let container = builder.build();
    assert!(container.is_ok());
    let foo = container.unwrap().resolve::<Foo>();
    assert!(foo.is_ok());
     
    // Invalid registration => 'as_type()' wasn't called
    let mut builder = he_di::ContainerBuilder::new();
    builder.register::<FooInvalidImpl>();
 
    let container = builder.build();
    assert!(container.is_err());
 
    if let DIError::RegistrationError(ValidatorError::EmptyValue(msg)) = container.unwrap_err() {
        let expected_msg = "invalid entry: Component 'FooInvalidImpl' hasn't been registered to a type (use `as_trait()` in the registration chain)".to_string();
        assert_eq!(msg, expected_msg);
    } else {
        panic!("invalid state > container should be a RegistrationError(EmptyValue)");
    }
 
    // Invalid registration => duplicate 
    let mut builder = he_di::ContainerBuilder::new();
    builder.register::<FooDuplicateImpl1>()
        .as_type::<FooDuplicate>();
    builder.register::<FooDuplicateImpl2>()
        .as_type::<FooDuplicate>();
 
    let container = builder.build();
    assert!(container.is_err());

    if let DIError::RegistrationError(ValidatorError::MultipleErrors(errs)) = container.unwrap_err() {
        assert_eq!(errs.len(), 2);

        // Order of errors isn't guaranteed
        let expected_err = ValidatorError::IllegalValue("duplicate entry: multiple components are registered to type FooDuplicate > FooDuplicateImpl1".to_string());
       assert!(errs.iter().find(|err| err == &&expected_err).is_some());
 
        let expected_err = ValidatorError::IllegalValue("duplicate entry: multiple components are registered to type FooDuplicate > FooDuplicateImpl2".to_string());
        assert!(errs.iter().find(|err| err == &&expected_err).is_some());
    } else {
        panic!("invalid state > container should be a RegistrationError(MultipleErrors([IllegalValue,IllegalValue]))");
    }
}