Module named_dependencies

Aedi, a dependency injection library.

Aedi is a dependency injection library. It does provide a set of containers that do IoC, and an interface to configure application components (structs, objects, etc.)

Aim

The aim of library is to provide a dependency injection solution that is feature rich, easy to use, easy to learn, and easy to extend up to your needs.

Usage

This tutorial will show how to register a component with custom identity in container, and how to reference components with custom identities. The tutorial is based on car simulation presented in previous example, and will continue to improve it.

Except of a single implementation of a component, in some occurrences of an application, multiple instances of same type of component, but with varying dependencies, are required. In case of car simulation application, the simulator should not be limited to only a single car, it should be able to have multiple cars with varying parameters, like cars of sedan or smart sizes with blue and green colors.

Previous section showed how to register only one version for each component including the car itself. Attempting to add another car to container like in example below, will fail due to simple problem: Both cars are identified in container by their type.

register!Car
    .construct(lref!Size)
    .set!"color"(lref!Color);

register!Car
    .construct(lref!Size)
    .set!"color"(Color(0, 0, 0));

Running in modified container configuration in context of previous tutorial's example will end in output from below, were last registered instance of Car component overrides the previously defined.

You bought a new car with following specs:
Size:	Size(200, 150, 500)
Color:	Color(0, 0, 0)

Each registered component in a container is associated with an identity in it. In case with car for previous examples, the Car component is associated with identity representing it’s Type. To avoid associating a component by it’s type during registration, pass it’s identity as an argument to register method, like in example below. A component can also be associated with an interface it implements by inserting desired interface before the type of registered component.

with (container.configure) {
    register!Color("color.green") // Register "green" color into container.
        .set!"r"(cast(ubyte) 0)
        .set!"g"(cast(ubyte) 255)
        .set!"b"(cast(ubyte) 0);

    register!Color("color.blue") // Register "blue" color into container.
        .set!"r"(cast(ubyte) 0)
        .set!"g"(cast(ubyte) 0)
        .set!"b"(cast(ubyte) 255);

    register!Size("size.sedan") // Register a size of a generic "sedan" into container
        .set!"width"(200UL)
        .set!"height"(150UL)
        .set!"length"(500UL);

    register!Size("size.smart_car") // Register a size of a generic smart car into container
        .set!"width"(200UL)
        .set!"height"(150UL)
        .set!"length"(300UL);

    register!Car("sedan.green") // Register a car with sedan sizes and of green color.
        .construct("size.sedan".lref)
        .set!"color"("color.green".lref);

    register!Car("smarty.blue") // Register a car with smart car sizes and of a blue color.
        .construct("size.smart_car".lref)
        .set!"color"("color.blue".lref);

    register!Car("sedan.blue") // Register a car with sedan car sizes and of a blue color.
        .construct("size.sedan".lref)
        .set!"color"("color.blue".lref);
}

To reference a component that has custom identity, in a configuration or reliant component, use lref("custom-associated-identity") notation. Seeing this type of reference, framework will attempt to search component by this identity, and serve it to component that is in con- struction. Thanks to unified function call syntax (UFCS) available in D programming language, lref("custom-associated-identity") can be rewritten into a more pleasant view "custom-associated-identity".lref. To extract manually a component with custom identity pass the identity to locate method as first argument, along with type of component.

Running fixed version of configuration, will yield in printing all three cars from code above into stdout in output below. To be sure that all modifications done in this tutorial are working, run the application to see following output:

You bough a new car sedan green with following specs:
Size:	Size(200, 150, 500)
Color:	Color(0, 255, 0)
You bough a new car sedan blue with following specs:
Size:	Size(200, 150, 500)
Color:	Color(0, 0, 255)
You bough a new car smarty blue with following specs:
Size:	Size(200, 150, 300)
Color:	Color(0, 0, 255)

Check example below. Play with it, to get the gist of named components.

Functions

NameDescription
main()
print(car, name)

Classes

NameDescription
Car A class representing a car.

Structs

NameDescription
Color A struct that should be managed by container.
Size Size of a car.