derive_di 0.2.2

This crate is realized the dependency injection pattern
Documentation
# Dependency Injection pattern derive
[![](https://github.com/Mnwa/derive_di/workflows/build/badge.svg?branch=master)](https://github.com/Mnwa/derive_di/actions?query=workflow%3Abuild)
[![](https://docs.rs/derive_di/badge.svg)](https://docs.rs/derive_di/)
[![](https://img.shields.io/crates/v/derive_di.svg)](https://crates.io/crates/derive_di)
[![](https://img.shields.io/crates/d/derive_di.svg)](https://crates.io/crates/derive_di)

Rust macro to automatically implement the **dependency injection** pattern for arbitrary structs.
A simple `#[derive(Container)]` will generate new getters and setters for every field of your struct.
Also, the Container will implement the `Default` trait, where will inject every field with `Injectable` trait.

## Simple example
```rust
use derive_di::*;
#[injectable]
#[derive(Default)]
struct InjectableStruct;

#[derive(Container)]
struct MyContainer {
    i_struct: InjectableStruct,
}
```

That code, which will be generated for you

```rust
use derive_di::*;

#[derive(Default)]
struct InjectableStruct;
impl Injectable for InjectableStruct {
    fn get_service() -> Self {
        Default::default()
    }
}

struct MyContainer {
    i_struct: InjectableStruct,
}

impl MyContainer {
    pub fn get_i_struct(&self) -> &InjectableStruct {
        &self.i_struct
    }
    pub fn get_mut_i_struct(&mut self) -> &mut InjectableStruct {
        &mut self.i_struct
    }
    pub fn set_i_struct(&mut self, i_struct: InjectableStruct) {
        self.i_struct = i_struct
    }
}

impl Default for MyContainer {
    fn default() -> Self {
        Self {
            i_struct: Injectable::get_service()
        }
    }
}
```

## Additional features

### Factory
You can pass any factory to the `injectable` macro for building you struct.

#### Factory struct
You can build you struct inside `injectable` macro.
```rust
#[injectable(factory => InjectableStruct {inner: "test".to_owned()})]
struct InjectableStruct {
    inner: String,
}
```
The `Injectable` will be look like this
```rust
impl Injectable for InjectableStruct {
    fn get_service() -> Self {
        InjectableStruct {inner: "test".to_owned()}
    }
}
```

#### Factory fn
You can build you struct inside `injectable` macro with factory method.
```rust
fn factory_struct() -> InjectableStruct {
    InjectableStruct {
        inner: "test".to_owned(),
    }
}
#[injectable(factory => factory_struct())]
struct InjectableStruct {
    inner: String,
}
```
The `Injectable` will be look like this
```rust
impl Injectable for InjectableStruct {
    fn get_service() -> Self {
        factory_struct()
    }
}
```
#### Factory closure
You can build you struct inside `injectable` macro with factory closure.
```rust
#[injectable(factory => || InjectableStruct {inner: "test".to_owned()})]
struct InjectableStruct {
    inner: String,
}
```
The `Injectable` will be look like this
```rust
impl Injectable for InjectableStruct {
    fn get_service() -> Self {
        (|| InjectableStruct {inner: "test".to_owned()})()
    }
}
```

### Auto injecting a structs to the `dyn Trait` container fields
With the `inject` macro, you can easy to solve `dyn Trait` fields in tou container.
```rust
#[injectable(factory => InjectableStruct)]
struct InjectableStruct;

trait Getter {
    fn get(&self) -> String;
}

impl Getter for InjectableStruct {
    fn get(&self) -> String {
        "test".to_owned()
    }
}

#[derive(Container)]
struct MyContainer {
    #[inject(InjectableStruct)]
    i_struct: Box<dyn Getter>,
}
```
The `Default` impl of the`MyContainer` will be looks like

```rust
impl Default for MyContainer {
    fn default() -> Self {
        Self {
            i_struct: Box::from(InjectableStruct::get_service())
        }
    }
}
```

### Mocks
You can combine the `dyn Trait` fields and setters in your container
and mock any logic for simple testing.

```rust
#[injectable(factory => || InjectableStruct)]
struct InjectableStruct;

trait Getter {
    fn get(&self) -> String;
}

impl Getter for InjectableStruct {
    fn get(&self) -> String {
        "test".to_owned()
    }
}

struct GetterMock;
impl Getter for GetterMock {
    fn get(&self) -> String {
        "mocked".to_owned()
    }
}

#[derive(Container)]
struct MyContainer {
    #[inject(InjectableStruct)]
    i_struct: Box<dyn Getter>,
}

fn main() {      
    let mut container = MyContainer::default();
    assert_eq!("test", container.get_i_struct().get());
    container.set_i_struct(Box::from(GetterMock));
    assert_eq!("mocked", container.get_i_struct().get())
}
```