multiple_containers

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.

In most simple applications, a single container, like singleton or prototype one might be enough, for using. Having a set of singletons constructed on behalf of a developer is convenient, yet there are occurences a single container is not enough. For example when, a set of components rely on a particular dependency, and more specifically, the dependency they rely upon, should not be shared across reliant components. In another case, a set of components are stored in a database, in serialized form, and they are used as dependencies for other components from application.

In such cases use of a single container like singleton or prototype is not enough, since one set of components should be created by using normal frameworks means, and another set needs to be fetched from a database, or should not be shared to all dependent components. To solve this problem, AEDI framework, allows container to be joined and used together, for creation of components. A component in such a joint container, having a dependency on a prototype component, will have it’s requirement fullfilled without a problem.

Using as an example car simulation app, the company decided to add a set ”tires” to simulated cars. For a particular car, each tire installed in it has same properties as other installed in same car. Registering 4 times same tire is not cost effective. Instead of it, it is better to register component into a prototype container and use component to supply 4 instances of a tire to a particular car. Example below shows how two or more containers can be joined together, configured with components, and used to instantiate required components.

auto container = aggregate( // Create a joint container hosting other two containers
        singleton(), "singleton", // Create singleton container, and store it in joint container by "singleton" identity
        prototype(), "prototype" // Create prototype container, and store it in joint container by "prototype" identity
    );

with (container.configure("singleton")) { // Configure singleton container

    // ...

    register!Car
        .autowire
        .autowire!"color"
        .set!"frontLeft"(lref!Tire)
        .set!"frontRight"(lref!Tire)
        .set!"backLeft"(lref!Tire)
        .set!"backRight"(lref!Tire);
}

with (container.configure("prototype")) { // Configure prototype container

    register!Tire // Registering Tire into "prototype" container used by aggregate container
        .set!"size"(17)
        .set!"pressure"(3.0)
        .set!"vendor"("divine tire");
}

//...

To join one or more containers together, an aggregate container must be created that will host both of them under the hood. Once aggregate container has all of joint containers registered in it, the process of registering components takes place. To register components in joint container, pass the identity of subcontainer (container in joint container) to configure as an argument, and register components for selected subcontainer. The configure function applied to joint container in with () statement creates a configuration context, that stores the container where components are stored, and container from which dependencies for those components should be fetched. In case of joint container, and singleton subcontainer, singleton subcontainer acts as storage while joint container is used as source for dependencies of registered components.

In the result, the car simulator will be able to use a car, that has 4 different instances of a tire. Output below shows the constructed car by joint containers.

Uuh, what a nice car, Electric car with following specs:
Size:	Size(200, 150, 300)
Color:	Color(0, 0, 0)
Engine:	app.ElectricEngine
Tire front left:	Tire(17 inch, 3 atm, divine tire)	 located at memory 7FB560C31180
Tire front right:	Tire(17 inch, 3 atm, divine tire)	 located at memory 7FB560C311C0
Tire back left: 	Tire(17 inch, 3 atm, divine tire)	 located at memory 7FB560C31200
Tire back right:	Tire(17 inch, 3 atm, divine tire)	 located at memory 7FB560C31240

Notice that each tire is a different object, hence everything is working as we expected!

Try this example, modify it, play with it to understand how compositing can help in designing your application.

Members

Classes

Car
class Car

A class representing a car.

CarManufacturer
class CarManufacturer

A manufacturer of cars.

DieselEngine
class DieselEngine

A concrete implementation of Engine that uses diesel for propelling.

ElectricEngine
class ElectricEngine

A concrete implementation of Engine that uses electricity for propelling.

GasolineEngine
class GasolineEngine

A concrete implementation of Engine that uses gasoline for propelling.

Tire
class Tire

Tire, what it can represent else?

Functions

drive
void drive(Car car, string name)
Undocumented in source. Be warned that the author may not have intended to support it.
main
void main()
Undocumented in source. Be warned that the author may not have intended to support it.

Interfaces

Engine
interface Engine

Interface for engines.

Structs

Color
struct Color

A struct that should be managed by container.

Size
struct Size

Size of a car.

Meta

License

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:

The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Authors

aermicioi