Skip to content

mosure/inversify-cpp

 
 

Repository files navigation

inversify-cpp

Test Ubuntu Test MacOS Test Windows GitHub License GitHub Last Commit GitHub Releases Codacy Badge GitHub Downloads GitHub Issues Average time to resolve an issue

C++17 inversion of control and static dependency injection library.

Features

  • Constant, dynamic, and automatic resolvers
  • Singleton, resolution (TODO), and unique scopes

Documentation

Scope

Scope manages the uniqueness of a dependency.

Singleton scopes are cached after the first resolution and will be returned on subsequent inversify::get... calls.

Resolution scopes are cached throughout the duration of a single inversify::get... call. A dependency tree with duplicate dependencies will resolve each to the same cached value.

By default, the unique scope is used (except for constant values). The unique scope will resolve a unique dependency for each inversify::get... call.

Integration

#include <mosure/inversify.hpp>

// for convenience
namespace inversify = mosure::inversify;

Examples

Declare Interfaces

struct IFizz {
    virtual ~IFizz() = default;

    virtual void buzz() = 0;
};

using IFizzPtr = std::unique_ptr<IFizz>;

Declare Types

namespace symbols {
    using foo = inversify::Symbol<int>;
    using bar = inversify::Symbol<double>;
    using fizz = inversify::Symbol<IFizzPtr>;
    using fizzFactory = inversify::Symbol<std::function<IFizzPtr()>>;

    using autoFizzUnique = inversify::Symbol<std::function<IFizzUniquePtr>>;
    using autoFizzShared = inversify::Symbol<std::function<IFizzSharedPtr>>;
}

Declare Classes and Dependencies

struct Fizz : IFizz {
    Fizz(int foo, double bar)
        :
        foo_(foo),
        bar_(bar)
    { }

    void buzz() override {
        std::cout << "Fizz::buzz() - foo: " << foo_
                  << " - bar: " << bar_
                  << " - counter: " << ++counter_
                  << std::endl;
    }

    int foo_;
    int bar_;

    int counter_ { 0 };
};

template <>
struct inversify::Injectable<Fizz>
    : inversify::Inject<
        symbols::foo,
        symbols::bar
    >
{ };

Configure Bindings

Constant Values

Constant bindings are always singletons.

inversify::bind<symbols::foo>().toConstantValue(10);
inversify::bind<symbols::bar>().toConstantValue(1.618);
Dynamic Bindings

Dynamic bindings are resolved when calling inversify::get....

By default, dynamic bindings have resolution scope (e.g. each call to inversify::get... calls the factory).

Singleton scope dynamic bindings cache the first resolution of the binding.

inversify::bind<symbols::fizz>().toDynamicValue(
    [](const inversify::Context& ctx) {
        auto foo = inversify::get<symbols::foo>();
        auto bar = inversify::get<symbols::bar>();

        auto fizz = std::make_shared<Fizz>(foo, bar);

        return fizz;
    }
).inSingletonScope();
Factory Bindings

Dynamic bindings can be used to resolve factory functions.

inversify::bind<symbols::fizzFactory>().toDynamicValue(
    []() {
        return [](const inversify::Context& ctx) {
            auto foo = inversify::get<symbols::foo>();
            auto bar = inversify::get<symbols::bar>();

            auto fizz = std::make_shared<Fizz>(foo, bar);

            return fizz;
        };
    }
);
Automatic Bindings

Dependencies can be resolved automatically using an automatic binding. Injectables are a prerequisite to the type being constructed.

Automatic bindings can generate instances, unique_ptr's, and shared_ptr's of a class. The returned type is determined by the binding interface.

inversify::bind<symbols::autoFizzUnique>().to<Fizz>();
inversify::bind<symbols::autoFizzShared>().to<Fizz>().inSingletonScope();

Resolving Dependencies

auto bar = inversify::get<symbols::bar>();

auto fizz = inversify::get<symbols::fizz>();
fizz->buzz();

auto fizzFactory = inversify::get<symbols::fizzFactory>();
auto anotherFizz = fizzFactory();
anotherFizz->buzz();


auto autoFizzUnique = inversify::get<symbols::autoFizzUnique>();
autoFizzUnique->buzz();

auto autoFizzShared = inversify::get<symbols::autoFizzShared>();
autoFizzShared->buzz();

Running Tests

Use the following to run tests:

bazel run test --enable_platform_specific_config

Note: run the example app in a similar way: bazel run example --enable_platform_specific_config

Generating single_include Variant

Run python ./third_party/amalgamate/amalgamate.py -c ./third_party/amalgamate/config.json -s ./ from the root of the repository.

Thanks

  • InversifyJS - API design and inspiration for the project.

About

C++17 inversion of control and dependency injection container library.

Resources

License

Stars

Watchers

Forks

Packages

No packages published