https://github.com/mosure/inversify-cpp
C++17 inversion of control and dependency injection container library.
https://github.com/mosure/inversify-cpp
Last synced: 7 months ago
JSON representation
C++17 inversion of control and dependency injection container library.
- Host: GitHub
- URL: https://github.com/mosure/inversify-cpp
- Owner: mosure
- License: mit
- Created: 2020-12-17T05:08:27.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2023-09-19T22:11:27.000Z (about 2 years ago)
- Last Synced: 2025-03-31T04:36:41.460Z (8 months ago)
- Language: C++
- Homepage:
- Size: 219 KB
- Stars: 15
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-hpp - inversify-cpp - cpp?style=social)](https://github.com/mosure/inversify-cpp/stargazers/) | C++17 inversion of control and dependency injection container library. | [](https://opensource.org/licenses/MIT) | (Dependency Injection)
README
# inversify-cpp
[](https://github.com/Mosure/inversify-cpp/actions?query=workflow%3Aubuntu)
[](https://github.com/Mosure/inversify-cpp/actions?query=workflow%3Amacos)
[](https://github.com/Mosure/inversify-cpp/actions?query=workflow%3Awindows)
[](https://raw.githubusercontent.com/mosure/inversify-cpp/main/LICENSE)
[](https://github.com/mosure/inversify-cpp)
[](https://github.com/mosure/inversify-cpp/releases)
[](https://app.codacy.com/gh/Mosure/inversify-cpp/dashboard)
[](https://github.com/mosure/inversify-cpp/releases)
[](https://github.com/mosure/inversify-cpp/issues)
[](http://isitmaintained.com/project/mosure/inversify-cpp "Average time to resolve an issue")
C++17 inversion of control and dependency injection container library.
## Dependency Visualization
See the [inversify-cpp-visualizer](https://github.com/mosure/inversify-cpp-visualizer) project to generate dependency graphs.
## Features
* Constant, dynamic, and automatic resolvers
* Singleton, resolution (TODO), and unique scopes
## Documentation
### Installation
inversify-cpp supports conan. add `inversify-cpp/2.1.0` to your `conanfile.py`.
view the library on [conan center](https://conan.io/center/recipes/inversify-cpp)
### Scope
Scope manages the uniqueness of a dependency.
Singleton scopes are cached after the first resolution and will be returned on subsequent `container.get...` calls.
Resolution scopes are cached throughout the duration of a single `container.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 `container.get...` call.
## Integration
```cpp
#include
// for convenience
namespace inversify = mosure::inversify;
```
### Examples
#### Declare Interfaces
```cpp
struct IFizz {
virtual ~IFizz() = default;
virtual void buzz() = 0;
};
using IFizzPtr = std::unique_ptr;
```
#### Declare Types
```cpp
namespace symbols {
using foo = inversify::Symbol;
using bar = inversify::Symbol;
using fizz = inversify::Symbol;
using fizzFactory = inversify::Symbol>;
using autoFizzUnique = inversify::Symbol>;
using autoFizzShared = inversify::Symbol>;
}
```
> Note: symbols which hold the same interface type may do so via structs which inherit inversify::Symbol
#### Declare Classes and Dependencies
```cpp
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
: inversify::Inject<
symbols::foo,
symbols::bar
>
{ };
```
#### Configure Bindings
```cpp
inversify::Container<
symbols::foo,
symbols::bar
> container;
```
##### Constant Values
Constant bindings are always singletons.
```cpp
container.bind().toConstantValue(10);
container.bind().toConstantValue(1.618);
```
##### Dynamic Bindings
Dynamic bindings are resolved when calling `container.get...`.
By default, dynamic bindings have resolution scope (e.g. each call to `container.get...` calls the factory).
Singleton scope dynamic bindings cache the first resolution of the binding.
```cpp
container.bind().toDynamicValue(
[](auto& ctx) {
auto foo = ctx.container.template get();
auto bar = ctx.container.template get();
auto fizz = std::make_shared(foo, bar);
return fizz;
}
).inSingletonScope();
```
##### Factory Bindings
Dynamic bindings can be used to resolve factory functions.
```cpp
container.bind().toDynamicValue(
[](auto& ctx) {
return [&]() {
auto foo = ctx.container.template get();
auto bar = ctx.container.template get();
auto fizz = std::make_shared(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.
```cpp
container.bind().to();
container.bind().to().inSingletonScope();
```
#### Resolving Dependencies
```cpp
auto bar = container.get();
auto fizz = container.get();
fizz->buzz();
auto fizzFactory = container.get();
auto anotherFizz = fizzFactory();
anotherFizz->buzz();
auto autoFizzUnique = container.get();
autoFizzUnique->buzz();
auto autoFizzShared = container.get();
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/simple --enable_platform_specific_config`
## TODOS
* More compile-time checks
* Resolution scope
### Profiling
Run the following to generate a callgrind file:
* `bazel run example/profiling --enable_platform_specific_config --compilation_mode=dbg -s`
* `valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes ./bazel-bin/example/profiling/profiling`
## Containerless Version
See the [`containerless` branch](https://github.com/mosure/inversify-cpp/tree/containerless) for a static binding (containerless) version of the library.
## 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](https://inversify.io/) - API design and inspiration for the project.