aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 34358cf2fb396c521b004a455a6777b8330b9064 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

Syrette

Latest Version Documentation

The convenient dependency injection library for Rust.

Namesake

From the syrette Wikipedia article.

A syrette is a device for injecting liquid through a needle. It is similar to a syringe except that it has a closed flexible tube (like that typically used for toothpaste) instead of a rigid tube and piston.

Features

  • A dependency injection container
  • Autowiring dependencies
  • Binding factories
  • API inspired from the one of InversifyJS
  • Helpful error messages
  • Enforces the use of interface traits

Motivation

Other DI libraries for Rust are either unmaintained (di for example), overcomplicated and or bloated (anthill-di for example) or has a weird API (teloc for example).

The goal of Syrette is to be a simple, useful, convenient and familiar DI library.

Notice

Rust nightly is currently required.

Example usage

use syrette::{injectable, DIContainer};
use syrette::ptr::InterfacePtr;

trait IWeapon
{
    fn deal_damage(&self, damage: i32);
}

struct Sword {}

#[injectable(IWeapon)]
impl Sword
{
    fn new() -> Self
    {
        Self {}
    }
}

impl IWeapon for Sword
{
    fn deal_damage(&self, damage: i32)
    {
        println!("Sword dealt {} damage!", damage);
    }
}

trait IWarrior
{
    fn fight(&self);
}

struct Warrior {
    weapon: InterfacePtr<dyn IWeapon>,
}

#[injectable(IWarrior)]
impl Warrior
{
    fn new(weapon: InterfacePtr<dyn IWeapon>) -> Self
    {
        Self { weapon }
    }
}

impl IWarrior for Warrior
{
    fn fight(&self)
    {
        self.weapon.deal_damage(30);
    }
}

fn main()
{
    let mut di_container = DIContainer::new();

    di_container.bind::<dyn IWeapon>().to::<Sword>();

    di_container.bind::<dyn IWarrior>().to::<Warrior>();

    let warrior = di_container.get::<dyn IWarrior>().unwrap();

    warrior.fight();

    println!("Warrior has fighted");
}

For more examples see the examples folder.

Todo

  • Add support for generics