diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 7018df9..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/.kdev4
-/*.kdev4
-/.idea
-/cmake-build-debug
diff --git a/Benchmarks.md b/Benchmarks.md
index f1f3475..ec3f4bf 100644
--- a/Benchmarks.md
+++ b/Benchmarks.md
@@ -29,8 +29,8 @@ destroying all injected objects).
| Full injection time | 100 classes | 1000 classes |
|---------------------|-------------|---------------------------|
-| Clang 4.0.0 | 81-84 us | 2000-2100 us (2.0-2.1 ms) |
-| GCC 7.0.1 | 69-71 us | 1800 us (1.8 ms) |
+| Clang 4.0.0 | 81-84 μs | 2000-2100 μs (2.0-2.1 ms) |
+| GCC 7.0.1 | 69-71 μs | 1800 μs (1.8 ms) |
#### Injection time when using NormalizedComponent
@@ -42,8 +42,8 @@ calling the various `get*Component` functions).
| Fruit normalization time | 100 classes | 1000 classes |
|--------------------------|-------------|------------------|
-| Clang 4.0.0 | 80-82 us | 2000 us (2 ms) |
-| GCC 7.0.1 | 62-65 us | 1800 us (1.8 ms) |
+| Clang 4.0.0 | 80-82 μs | 2000 μs (2 ms) |
+| GCC 7.0.1 | 62-65 μs | 1800 μs (1.8 ms) |
And this is the time required to create an `Injector` from the `NormalizedComponent`, to inject the root class of the
dependency graph (which involves injecting all the other ones too, as dependencies) and finally the time to destroy the
@@ -51,8 +51,8 @@ injector (which involves destroying all injected objects).
| Per-injector time | 100 classes | 1000 classes |
|-------------------|-------------|--------------|
-| Clang 4.0.0 | 2.1-2.4 us | 94-95 us |
-| GCC 7.0.1 | 2-2.1 us | 96 us |
+| Clang 4.0.0 | 2.1-2.4 μs | 94-95 μs |
+| GCC 7.0.1 | 2-2.1 μs | 96 μs |
Here we assume that all classes need to be injected. However, in a real example we would use Fruit `Provider`s to only
inject the classes that are actually needed, so the time will be much lower. You can see an example of how to do that in
@@ -68,8 +68,8 @@ table of the "Per-injector time" (if you're using `NormalizedComponent`).
| New/delete time | 100 classes | 1000 classes |
|-----------------|-------------|--------------|
-| Clang 4.0.0 | 2.6 us | 45 us |
-| GCC 7.0.1 | 2.7-2.8 us | 37 us |
+| Clang 4.0.0 | 2.6 μs | 45 μs |
+| GCC 7.0.1 | 2.7-2.8 μs | 37 μs |
Note that in the 100 classes case, Fruit manages to be faster than raw new/delete when using `NormalizedComponent`. This
is thanks to Fruit's custom allocation strategy.
diff --git a/FAQ.md b/FAQ.md
deleted file mode 100644
index c3bce35..0000000
--- a/FAQ.md
+++ /dev/null
@@ -1,80 +0,0 @@
-#### How mature is this project?
-
-This project was started in May 2014, Fruit 1.0.0 was released in November 2014 and Fruit 3.0.0 was released in
-August 2017. Fruit now has extensive unit and integration tests.
-
-At the time of writing, Fruit is the most popular dependency injection library for C++ (at least, it's the first result
-in a [Google search](https://www.google.co.uk/search?q=C%2B%2B+dependency+injection) for "C++ dependency injection" and
-it's
-[the top C++ dependency injection library](https://github.com/search?l=&o=desc&q=dependency+injection+language%3AC%2B%2B&ref=advsearch&s=stars&type=Repositories)
-by number of stars on Github).
-
-#### Why the name "Fruit"?
-
-Fruit is loosely inspired by the [Guice](https://github.com/google/guice) library for Java (pronounced as "juice"),
-which uses run-time checks (unlike Fruit where most checks occur at compile-time).
-
-_If you'd like some Guice but don't want to wait (for run-time errors), have some Fruit._
-
-It also hints to the fact that Fruit components have clearly-defined boundaries while Guice modules don't (all Guice
-modules have the same type) and to the fact that both Fruit and Guice are 100% natural (no need to run any code
-generation tools).
-
-#### Does Fruit use Run-Time Type Identification (RTTI)?
-
-Fruit **optionally** uses compile-time RTTI (i.e., it calls `typeid(T)` at compile time) to print type names in error
-messages.
-However, Fruit never calls `typeid` on an object, and never calls it at all at runtime.
-
-For the `typeid(T)` calls to work RTTI has to be enabled for the build, but you should not expect any performance
-degradation due to RTTI, since it's only used at compile time.
-
-If RTTI is disabled, Fruit will still compile and work, but if an injection error occurs Fruit won't be able to print
-the affected types as it otherwise would. It's therefore reasonable to have RTTI disabled in release builds, but
-enabled in debug builds. If you disable RTTI when building code that uses Fruit, you'll need to link against a Fruit
-build that also has RTTI disabled (note that the pre-packaged Fruit binaries have RTTI enabled).
-
-#### Fruit uses templates heavily. Will this have an impact on the executable size?
-
-Fruit uses templates heavily for metaprogramming, but the storage that backs injectors and components is *not*
-templated.
-
-Most of the templated methods are just wrappers and are written in such a way that they can be inlined by the compiler;
-so you should not expect a significant increase in the executable size due to the use of templates.
-
-See also the next question.
-
-#### Does Fruit have an impact on the executable size?
-
-If before using Fruit you were already using virtual classes, the impact on the executable size will be negligible.
-
-Otherwise, there will be a (likely small, but noticeable) increase due to the RTTI information for classes with virtual
-methods (if RTTI is enabled). Note that [RTTI can be disabled](faq#does-fruit-use-run-time-type-identification-rtti).
-
-In addition, for each binding there will be up to 4 additional symbols in the executable (one function to create the
-object, one function to destroy it and two static constants). The two functions are small forwarding functions, so the
-constructor/destructor of the injected type might get inlined into them; in this case 1 or 2 symbols can be saved.
-
-An example codebase with 100 interfaces, 100 (empty) classes, 100 component functions and 900 dependency edges between
-classes takes around `400 KB` (when compiled with GCC, with RTTI enabled).
-
-See also the [benchmarks page](benchmarks) and the next question.
-
-#### Does Fruit have an impact on performance?
-
-If before using Fruit you were already using virtual classes allocated with `new`, injection shouldn't have a noticeable
-impact on performance.
-
-Otherwise, there will be the cost of the memory allocations for implementation classes (if they were allocated on the
-stack before), and some speedup that was gained by inlining functions into their callers might also be lost.
-
-There are benchmarks results for various compilers in the [benchmarks page](benchmarks). The summary is that with 100
-injected interfaces, 100 implementation classes and 900 dependency edges between them, the injection time (creation of
-the injector + injection of all the 100 classes) is around 70 us (when using GCC).
-
-When using `NormalizedComponent` to pre-collect the bindings (while still having a separate injector for each request),
-you can pay the 70 us cost once and then pay only 2 us at injection time (creation of the injector + injection of all
-100 classes).
-
-So creating an injector for each request (in addition to the single injector created during the server startup) can be
-reasonable, depending of course on your performance requirements.
diff --git a/Home.md b/Home.md
deleted file mode 100644
index 6bd06e6..0000000
--- a/Home.md
+++ /dev/null
@@ -1,101 +0,0 @@
-## What is Fruit?
-
-Fruit is a [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) framework for C++, loosely inspired
-by the Guice framework for Java. It uses C++ metaprogramming together with some new C++11 features to detect most
-injection problems at compile-time. The code has also been optimized so that using injection adds very little overhead
-(more details in the [benchmarks page](benchmarks)).
-
-It allows to split the implementation code in "components" (aka modules) that can be assembled to form other components.
-
-From a component it's then possible to create an injector, that can create instances of the classes registered in the
-component.
-
-The code is on github at [github.com/google/fruit](https://github.com/google/fruit) and
-[prebuilt packages](https://github.com/google/fruit/wiki/install#prebuilt-packages) are available.
-
-## Features
-
-* Main features:
- * Binding of a type to an interface, [details here](quick-reference#bindings)
- * Inject annotations for constructors, [details here](quick-reference#inject-macro)
- * Binding to a provider (lambda), [details here](quick-reference#providers)
- * Binding to an instance/value, [details here](quick-reference#binding-instances)
- * Annotated bindings, [details here](quick-reference#annotated-injection)
- * Assisted injection, [details here](quick-reference#factories-and-assisted-injection)
- * Automatic registration of factories for a type I if there is a factory for C and I is bound to C,
- [details here](quick-reference#bindings)
-* Unlike most DI frameworks, most checks are done at **compile time**, so that errors can be caught early. Some
- examples of checks done at compile time:
- * Checking that all required types are bound (implicitly or explicitly)
- * Checking that there are no dependency loops in the bound types.
-* The only injection errors that can't be detected at compile time (and will be detected at run-time) are:
- * When a type has multiple inconsistent bindings in different components.
- * When two `Component` functions `install()` each other.
- * When a user-defined lambda passed to `registerProvider` or `registerMultibindingProvider` returns `nullptr`.
- * When attempting to replace a `Component` (using `replace(...).with(...)` after the replaced componed is
- installed).
-* No code generation. Just include `fruit/fruit.h` and link with the `fruit` library.
-* Not intrusive. You can bind interfaces and classes without modifying them (e.g. from a third-party library that
- doesn't use Fruit).
-* Reduces the need of `#include`s. The header file of a component only includes the interfaces exposed by the
- component. The implementation classes and the interfaces that the component doesn't expose (for example, private
- interfaces that the client code doesn't need to know about) don't need to be included. So after changing the binding
- of a type in a component (as long as the interfaces exposed by the component remain the same) only the component
- itself needs to be re-compiled. Any components and injectors that use that component **don't** need to. This makes
- compilation of large projects much faster than an include-all-the-classes-I-need-to-inject approach.
-* Helps with binary compatibility: as a consequence of the previous point, since the client code doesn't include the
- implementation classes (not even the header files) if the interfaces exported by the component didn't change the
- compiled client code is binary compatible with the new implementation.
-* No internal static data. This allows the creation of separate injectors in different parts of a system (even
- concurrently), which might bind the same type in different ways.
-* Conditional injection based on runtime conditions. This allows to decide what to inject based on e.g. flags passed
- to the executable or an XML file loaded at runtime.
- * Note that you don't need special support in Fruit for the way that you use to decide what to inject. For
- example, if you'd like to determine the classes to inject based on the result of an RPC to a server sent using a
- proprietary RPC framework, you can do this and you don't need to modify Fruit.
-* The combination of the previous two features means that at runtime you can decide to create a separate injector with
- a different configuration. E.g. think of a web server that receives a notification to reconfigure itself, creates a
- component with the new configuration for new requests and then deletes the old one when there are no more requests
- using it, never stopping serving requests.
-* Optional eager injection: after calling a specific method on the injector, multiple threads can use the same
- injector concurrently with no locking.
-* Multi-bindings: unlike the typical binding when in an injector there's a single binding for each type,
- multi-bindings allow components to specify several bindings and the collection of bound instances can be retrieved
- from the injector. This can be useful for e.g. plugin loading/hooks, or to register request handlers in a server.
-
-Eager to get started? Jump to the [Getting started](https://github.com/google/fruit/wiki/tutorial:-getting-started)
-page of the tutorial.
-
-Look at the [examples/](https://github.com/google/fruit/tree/master/examples) directory in the source tree for example
-code, or see the [FAQ page](faq) for more information.
-
-#### Rejected features
-
-* Compile-time detection of multiple inconsistent bindings. This feature has been rejected because it would interfere
- with some of the features above that are considered more important (conditional injection, binary compatibility,
- few includes).
-* Injection scopes, e.g. binding a type/value only for the duration of a request. This feature was implemented and
- then removed, replaced by the use of `NormalizedComponent`. If you need to create many injectors that have most of
- the bindings in common, `NormalizedComponent` allows to save most of work involved in the injector creation (but
- there will still be separate injectors). See
- [the server page in the tutorial](https://github.com/google/fruit/wiki/tutorial:-server) for an example use of
- `NormalizedComponent` with per-request injectors.
-
-Do you have a feature in mind that's not in the above list? Drop me an email
-([poletti.marco@gmail.com](mailto:poletti.marco@gmail.com)), I'm interested to hear your idea and I'll implement it if
-feasible.
-
-### License
-
-The code is released under the Apache 2.0 license. See the
-[COPYING](https://github.com/google/fruit/blob/master/COPYING) file for more details.
-
-This project is not an official Google project. It is not supported by Google and Google specifically disclaims all
-warranties as to its quality, merchantability, or fitness for a particular purpose.
-
-### Contact information
-
-Currently [Marco Poletti](https://github.com/poletti-marco) ([poletti.marco@gmail.com](mailto:poletti.marco@gmail.com))
-is the only regular developer of this project.
-
-Occasional contributors: [Jason Mealler](https://github.com/jmealler), [Maxwell Koo](https://github.com/mjkoo)
diff --git a/Install.md b/Install.md
deleted file mode 100644
index d69a87f..0000000
--- a/Install.md
+++ /dev/null
@@ -1,120 +0,0 @@
-### Dependencies
-
-Fruit's only dependency is on the Boost hashset/hashmap implementation. Even that is optional: you can switch to the
-STL implementation by passing the flag `-DFRUIT_USES_BOOST=False` to CMake. In any case, the Boost library is only
-required when building Fruit itself and not when building code that uses Fruit.
-
-Also, Fruit uses many C++11 features so you need to use a relatively recent compiler in C++11 mode (or later).
-**This is not just to build Fruit itself, but also to build any code that uses Fruit.**
-
-The supported compiler/STL/OS combinations are:
-
-* GCC 5.0.0 or later on Linux and OS X
-* MinGW's GCC 5.0.0 or later on Windows
-* Clang 3.5 or later using stdlibc++ (GCC's STL) on Linux
-* Clang 3.5 or later using libc++ on Linux and OS X
-* MSVC 2017 or later on Windows
-
-That said, any C++11-compliant compiler should work on any platform.
-
-Compilers known _not_ to work due to a lacking C++11 support and/or compiler bugs:
-
-* Intel compiler ([bug1](https://software.intel.com/en-us/comment/1862049),
- [bug2](https://software.intel.com/en-us/comment/1854501))
-
-If you find any other compiler/platform where Fruit doesn't work, feel free to
-[contact me](mailto:poletti.marco@gmail.com) and I can take a look.
-
-### Prebuilt packages
-
-Prebuilt packages for Fedora, openSUSE, Ubuntu, Debian and various other distributions are available. These packages are
-built using GCC, and **they may not work if you want to compile your project with Clang or other compilers**. In that
-case, see the section below on how to compile Fruit manually.
-
-**[Choose your distribution here](http://software.opensuse.org/download.html?project=home%3Apoletti_marco&package=libfruit)**
-
-After following the instructions there, to install the headers (necessary to compile programs that use Fruit):
-
-* For Fedora, openSUSE, RHEL, CentOS, SLE: install the `libfruit-devel` package.
-* For *Ubuntu, Debian: install the `fruit-dev` package.
-* For Arch: nothing to do, the headers are already installed.
-
-I will write packages or build files for other distributions on request. Or if you write one, please send it to me and I
-will publish it here.
-
-### Building Fruit manually
-
-In most cases you can (and should) use the prebuilt packages instead, see the previous section.
-
-#### With CMake, on Linux/OS X
-
-For building Fruit, you'll need to have `cmake` and `make` installed, together with a recent version of GCC/Clang (see
-above).
-
-First, get the code from Github: [https://github.com/google/fruit/releases](https://github.com/google/fruit/releases)
-
-To configure and build:
-
- cmake -DCMAKE_BUILD_TYPE=Release . && make -j
-
-Or if you don't want to use Boost:
-
- cmake -DCMAKE_BUILD_TYPE=Release -DFRUIT_USES_BOOST=False . && make -j
-
-To install (under Linux this uses `/usr/local`):
-
- sudo make install
-
-To configure for installation in a specific directory, e.g. `/usr`:
-
- cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr . && make -j
-
-The above instructions are the simplest to get started, but out-of-source builds are also supported.
-
-#### With MSVC, on Windows
-
-You can import Fruit in Visual Studio (2017 and later) as a CMake project. You need to set the relevant CMake flags in
-the `CMakeSettings.json` file that Visual Studio will create.
-For example, if you installed Boost in `C:\boost\boost_1_62_0`, you can put this configuration in your
-`CMakeSettings.json`:
-
- {
- "configurations": [
- {
- "name": "x64-Release",
- "generator": "Visual Studio 15 2017 Win64",
- "configurationType": "Release",
- "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Release",
- "buildCommandArgs": "-m -v:minimal"
- }
- ]
- }
-
-Or if you don't want to use Boost, you can use:
-
- {
- "configurations": [
- {
- "name": "x64-Release",
- "generator": "Visual Studio 15 2017 Win64",
- "configurationType": "Release",
- "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DFRUIT_USES_BOOST=False -DCMAKE_BUILD_TYPE=Release",
- "buildCommandArgs": "-m -v:minimal"
- }
- ]
- }
-
-You can now run CMake within Visual Studio (from the menu: CMake -> Cache -> Generate -> CMakeLists.txt) and build Fruit
-(from the menu: CMake -> Build All).
-
-For more information (e.g. how to run Fruit tests in MSVC) see the
-[CONTRIBUTING.md](https://github.com/google/fruit/blob/master/CONTRIBUTING.md) file.
-
-
-#### With Bazel, on Linux
-
-Building with [Bazel](http://bazel.io) is also supported. You should import the `fruit/extras/bazel_root` directory,
-not the Fruit root. See the [CONTRIBUTING.md](https://github.com/google/fruit/blob/master/CONTRIBUTING.md) file
-for more details.
diff --git a/Quick-reference.md b/Quick-reference.md
deleted file mode 100644
index f808a28..0000000
--- a/Quick-reference.md
+++ /dev/null
@@ -1,1007 +0,0 @@
-
-This page is a quick reference for Fruit features, it's intended for people that already know the basics of Fruit. If
-you're just starting to learn Fruit, read the [tutorial](https://github.com/google/fruit/wiki/tutorial:-getting-started)
-first.
-
-#### Table of contents
-
-* [Constructor injection](#constructor-injection)
-* [Bindings](#bindings)
-* [Multibindings](#multibindings)
-* [Providers](#providers)
-* [Binding instances](#binding-instances)
-* [Annotated injection](#annotated-injection)
-* [Factories and assisted injection](#factories-and-assisted-injection)
-* [Type of a component, components with requirements and automatic bindings](#type-of-a-component-components-with-requirements-and-automatic-bindings)
-* [Injector](#injector)
-* [Normalized components](#normalized-components)
-* [Injection scopes](#injection-scopes)
-* [Eager injection](#eager-injection)
-* [Lazy injection](#lazy-injection)
-* [Templated and parametrized components](#templated-and-parametrized-components)
-
-
-## Constructor injection
-
-#### INJECT macro
-
-The simplest way to define that a class should be injected using a constructor is to wrap the prototype of that
-constructor in the class definition with the INJECT macro.
-
- class GreeterImpl : public Greeter {
- private:
- Writer* writer;
-
- public:
- INJECT(GreeterImpl(Writer* writer))
- : writer(writer) {
- }
-
- // ...
- };
-
-
-
-
-
-The constructor can then be defined inside the class definition (as in the snippet above) or just declared there and
-defined out of the class (for example, in a `.cpp` file if the class definition is in a header file). If the constructor
-is defined elsewhere, only the prototype in the class definition should be wrapped in `INJECT()`, the constructor
-definition shouldn't be.
-
-Note that where constructor injection is desired, even 0-argument constructors must be explicitly registered, whether or
-not they are user-defined. Fruit never uses a constructor unless that constructor has been explicitly marked as the one
-that should be used for injection. This is to avoid undesired constructor injection of value types; e.g. if
-`std::vector` is not bound it's likely that the programmer forgot and Fruit reports an error if this binding
-is missing, rather than silently constructing an empty vector.
-
- class StdoutWriter : public Writer {
- public:
- INJECT(StdoutWriter()) = default;
-
- // ...
- };
-
-
-
-
-
-The INJECT macro can only be used when the constructor has a simple signature. It can't be used with any of the
-following:
-
-* An explicit `inline` specifier at the point of declaration of the constructor. In this case, the specifier could be
- removed since for constructors defined in the class definition it's implicit, while for constructors defined outside
- the class it's the `inline` specifier at the point of definition that counts. However if it's present it interferes
- with the `INJECT()` macro.
-* Templated constructors. In this case, you should use `registerProvider` instead.
-* Constructors with default values for parameters. In this case, you should use an `Inject` typedef or
- `registerConstructor` instead.
-
-Note that the restriction on templates is only when the constructor itself is templated. `INJECT()` **can** be used for
-templated classes, as long as the constructor is not also templated.
-
- template
- class GreeterImpl : public Greeter {
- private:
- W* writer;
-
- public:
- INJECT(GreeterImpl(W* writer))
- : writer(writer) {
- }
-
- // ...
- };
-
-
-
-
-
-The `INJECT()` macro can also be used when only some of the constructor parameters should be injected, see
-[assisted injection](quick-reference#factories-and-assisted-injection) for more details.
-
-#### Inject typedef
-
-When the `INJECT()` macro can't be used (or as an alternative to avoid using macros) an `Inject` typedef can be defined
-inside the class instead, with the constructor signature. The two examples in the INJECT section can be rewritten as:
-
- class GreeterImpl : public Greeter {
- private:
- Writer* writer;
-
- public:
- GreeterImpl(Writer* writer)
- : writer(writer) {
- }
-
- typedef GreeterImpl(Writer*) Inject;
- // Or:
- // using Inject = GreeterImpl(Writer*);
-
- // ...
- };
-
-
-
-
-
- class StdoutWriter : public Writer {
- public:
- StdoutWriter() = default; // Optional if no other constructors are defined
-
- typedef StdoutWriter() Inject;
- // Or:
- // using Inject = StdoutWriter();
-
- // ...
- };
-
-
-
-
-
-And these are two examples that couldn't be written using the `INJECT()` macro:
-
- class StdoutWriter : public Writer {
- public:
- StdoutWriter(const char* line_terminator = "\n");
-
- typedef StdoutWriter() Inject;
- // Or:
- // using Inject = StdoutWriter();
-
- // ...
- };
-
-
-
-
-
- class GreeterImpl : public Greeter {
- private:
- Writer* writer;
-
- public:
- template
- GreeterImpl(W* writer)
- : writer(writer) {
- }
-
- template
- GreeterImpl(std::unique_ptr writer)
- : writer(writer.get()) {
- }
-
- typedef GreeterImpl(Writer*) Inject;
- // Or:
- // using Inject = GreeterImpl(Writer*);
-
- // ...
- };
-
-
-
-
-
-In the last example the first templated constructor will be used, with `W`=`Writer`. The usual overloading resolution
-(with template parameter deduction) is performed to determine the constructor to use for injection.
-
-As the `INJECT` macro, the `Inject` typedef can also be used when only some of the constructor parameters should be
-injected, [see assisted injection](quick-reference#factories-and-assisted-injection) for more details.
-
-#### registerConstructor()
-
-While the `Inject` typedef doesn't have some of the limitations of the `INJECT()` macro, there are some situations where
-even the typedef is not flexible enough:
-
-* If you can't modify the class definition. This is typically because the class is a third-party class that is not
- under our control, and the third-party library doesn't use Fruit. Also, a similar situation would occur if you're
- trying Fruit in an existing codebase and you want to keep Fruit-specific code separate from the existing code.
-* If the class should be injected using that constructor only in some cases. For example, in other cases you want a
- different constructor for that class, or you want to use a provider instead of constructor injection.
-
-The solution here is the `registerConstructor()` method available when constructing a component.
-
- class GreeterImpl : public Greeter {
- private:
- Writer* writer;
-
- public:
- GreeterImpl(Writer* writer)
- : writer(writer) {
- }
-
- // ...
- };
-
- fruit::Component, Greeter> getGreeterComponent() {
- return fruit::createComponent()
- .registerConstructor()
- .bind();
- }
-
-
-
-
-
-
-The `registerConstructor()` alone can be modelled as:
-
-
-
-
-
-If only some of the constructor parameters should be injected, see
-[the section on assisted injection](quick-reference#factories-and-assisted-injection).
-
-If none of the constructors does the desired initializations, see the [section on providers](quick-reference#providers)
-to see how to bind a lambda function instead.
-
-## Bindings
-
-`bind()` specifies that `Interface` can be injected from an object of type `Impl`. `Impl` must be a
-class derived from `Interface`.
-It can also bind factories, i.e. bind `std::function(T1,...,Tn)>` to
-`std::function(T1,...,Tn)>` or `std::function`, for any parameter types
-`T1,...,Tn`.
-
-See the section on [factories and assisted injection](quick-reference#factories-and-assisted-injection) to see a
-convenient way how to bind a `std::function(T1,...,Tn)>` in the first place.
-
-
-
-
-
-## Multibindings
-
-Multibindings are a feature of Fruit (inspired by Guice) that allows to bind the same type multiple times, in different
-ways. They can be used to bind plugins, listeners, etc.
-
-Also, since there are no constraints to the number of bindings (even 0 is allowed), they can be used for optional
-injection: «if T is bound, then get an instance of T and ...», however in this case T must be bound as a multibinding
-and not as a normal binding. See [lazy injection](quick-reference#lazy-injection) instead if you want something like
-«if (...) then inject T» with T always bound but expensive to inject.
-
-The multibindings for a given type are completely separate from the normal bindings; in most cases a type will have
-either multibindings or bindings, but not both.
-
-Multibindings can depend on normal bindings (e.g. using constructor injection) but they can't depend on other
-multibindings.
-
-Unlike normal bindings, multibindings do **not** contribute to a Component type. E.g. a component with multibindings for
-Foo and a binding for Bar will have type `fruit::Component`, not `fruit::Component`. This allows to add
-multibindings for any type in any component without exposing this in the component type.
-
-Unlike normal bindings, Fruit will not attempt to remove duplicate multibindings, even if they are
-"the same multibinding".
-
-Example usage:
-
- fruit::Component<> getListenerComponent() {
- return fruit::createComponent()
- .addMultibinding()
- .addMultibinding();
- }
-
- const std::vector& listeners = injector.getMultibindings();
- for (Listener* listener : listeners) {
- listener->notify();
- }
-
-Note that here we specify all multibindings in a single `Component`, but this is not necessary; as for normal bindings,
-Fruit will collect the multibindings in all components used to create the injector.
-
-## Providers
-
-This section is about registering providers. For `fruit::Provider`, see the section on
-[lazy injection](quick-reference#lazy-injection).
-
-The simplest way to register a class for injection is using constructor injection. However, sometimes there is no
-constructor that does the desired initialization, and it's not possible to add one (e.g for third-party classes) or it's
-not reasonable to add one in that class (e.g. for value types, or if the constructor would have to do a too-complex
-task). In these cases, Fruit allows to construct the object using an arbitrary lambda function.
-
- class Database {
- public:
- static Database* open(std::string db_name, DbConnectionPool* pool);
-
- void setConnectionTimeout(int seconds);
- ...
- };
-
- fruit::Component getDatabaseComponent() {
- return fruit::createComponent()
- ... // Bind DbConnectionPool here
- .registerProvider([](DbConnectionPool* pool) {
- Database* db = Database::open("MyDb", pool);
- db->setConnectionTimeout(12);
- return db;
- });
- }
-
-
-
-
-
-If the lambda returns a pointer, as in the example above, Fruit will **take ownership** of that pointer and will call
-`delete` on that object when the injector is destroyed. If you don't want Fruit to take ownership, wrap the pointer in a
-holder struct or tuple (but note that you'll need to change the places where that type is used) or consider binding an
-instance.
-
-Instead, if the lambda returns a value, Fruit will move the value into the injector and then call the class destructor
-when the injector is destroyed. Note that this saves a memory allocation/deallocation, so it's preferable to
-return a value if possible.
-
-`registerProvider()` supports only lambdas with no captured variables (aka stateless lambdas). Plain functions are not
-supported (but you can wrap the function in a lambda).
-
-If you would like to bind a lambda with captures or a user-defined functor, it can still be done with a workaround.
-
-To use this user-defined functor:
-
- struct Functor {
- Functor(int n) {...}
- MyClass operator()(Foo* foo) {...}
- };
-
-Instead of:
-
- Component getMyClassComponent() {
- static const Functor aFunctor(42);
- return fruit::createComponent()
- ... // Bind Foo
- // Not allowed !!
- .registerProvider([=aFunctor](Foo* foo) { return aFunctor(foo); });
- }
-
-Write:
-
- Component getMyClassComponent() {
- static const Functor aFunctor(42);
- return fruit::createComponent()
- ... // Bind Foo
- .bindInstance(aFunctor)
- .registerProvider([](Functor functor, Foo* foo) { return functor(foo); });
- }
-
-
-
-
-
-## Binding instances
-
-In most cases, it's easier and less bug-prone to let Fruit manage the lifetime of injected objects. However, in some
-cases it's necessary to give Fruit access to some object external to the injector, and for which Fruit has no ownership.
-
-Binding instances is also a way to bind values that are constant during the lifetime of the injector, but vary between
-injectors; see the section on [normalized components](quick-reference#normalized-components).
-
- fruit::Component getFooComponent() {
- static Foo foo = createFoo();
- return fruit::createComponent()
- .bindInstance(foo);
- }
-
-
-
-
-
-It's also possible to bind constant values, however they then need to be marked as `const` in the `Component` type too:
-
- fruit::Component getFooComponent() {
- const static Foo foo = createFoo();
- return fruit::createComponent()
- .bindInstance(foo);
- }
-
-## Annotated injection
-
-There are cases when several implementation types might have the same "natural interface" they implement, except that
-only one of these types can be bound to it within a single injector. Annotated injection allows to have multiple
-bindings for the same type and to specify which binding is desired at each point of use. See the
-[tutorial page](https://github.com/google/fruit/wiki/tutorial:-annotated-injection) for a complete example.
-
-To bind a type using annotated injection, use `fruit::Annotated` instead of `T`, where `MarkerType` is
-any type you want to use to mark this binding for `T` (typically `MarkerType` is defined as an empty struct, for
-simplicity).
-
-Example binding:
-
- class MainBrakeImpl : public Brake {
- public:
- INJECT(MainBrakeImpl()) = default;
-
- // ...
- };
-
- fruit::Component> getMainBrakeComponent() {
- return fruit::createComponent()
- .bind, MainBrakeImpl>();
- }
-
-Example use:
-
- class CarImpl : public Car {
- private:
- Brake* mainBrake;
-
- public:
- INJECT(CarImpl(ANNOTATED(MainBrake, Brake*) mainBrake)
- : mainBrake(mainBrake) {
- }
- // Or:
- // using Inject = CarImpl(fruit::Annotated);
- // CarImpl(Brake* mainBrake)
- // : mainBrake(mainBrake) {
- // }
-
- // ...
- };
-
-Note that the `ANNOTATED` macro is only meant to be used within `INJECT`. Everywhere else you should write
-`fruit::Assisted<>` instead, both to define bindings that use annotated injection and to use them.
-
-Fruit supports annotated types instead of plain types everywhere it would make sense to use them (e.g. you can use
-`ASSISTED` and `ANNOTATED` parameters in the same constructor, you can use an annotated type in `bindInstance`).
-
-The only notable place where you should _not_ use annotated types is to annotate the class type in a constructor:
-
- class FooImpl : public Foo {
- private:
- Bar* bar;
- public:
- // Error, no need to use ANNOTATED here
- INJECT(ANNOTATED(MyAnnotation, FooImpl)(Bar* bar))
- : bar(bar) {
- }
- };
-
-When auto-injecting a class, Fruit already knows the correct annotation, so providing the annotation here would be
-redundant.
-
-Another thing to note when using annotated injection is that if you bind an implementation class to an interface using 2
-different annotations there will be only _one_ instance of the implementation class:
-
- class FooImpl : public Foo {
- public:
- INJECT(Foo()) = default;
- };
-
- struct First {};
- struct Second {};
- Component, fruit::Annotated>
- getFooComponent() {
-
- return fruit::createComponent()
- .bind, FooImpl>()
- .bind, FooImpl>(); // Allowed, but misleading!
- }
-
-That's because there is only one instance of every type in an injector (unless that type is annotated with multiple
-annotations, but `FooImpl` isn't). This is probably not what you want. In this case, you should also annotate the two
-implementation classes, so that the injector will contain a different instance for each annotation:
-
- class FooImpl : public Foo {
- public:
- INJECT(Foo()) = default;
- };
-
- struct First {};
- struct Second {};
- Component, fruit::Annotated>
- getFooComponent() {
-
- return fruit::createComponent()
- .bind, fruit::Annotated>()
- .bind, fruit::Annotated>();
- }
-
-Note that we did not change the definition of `FooImpl`, we only need to specify the annotation in the `bind()` calls.
-Fruit will then auto-inject `fruit::Annotated` and `fruit::Annotated`, both using
-`FooImpl`'s constructor.
-
-## Factories and assisted injection
-
-There are cases when within a single injector, multiple instances of a given class need to be created, either by
-repeatedly calling a single factory function (e.g. for threads in a thread pool) or because there is no single "correct"
-instance (different instances are required in different places). Instead of injecting a type `MyClass`, a
-`std::function()>` or `std::function(T1,...,Tn)>` can be injected
-instead.
-
-Example factory binding:
-
- class MyClass {
- public:
- MyClass(Foo* foo, int n);
- ...
- };
-
- Component(int)>> getMyClassComponent() {
- fruit::createComponent()
- ... // Bind Foo
- .registerFactory(Foo*, fruit::Assisted)>(
- [](Foo* foo, int n) {
- return std::unique_ptr(new MyClass(foo, n));
- });
- }
-
-
-
-
-
-Example use of the binding from the injector:
-
- std::function(int)> myClassFactory(injector);
- std::unique_ptr x = myClassFactory(15);
-
-Example use of the binding to inject another class:
-
- class Bar {
- public:
- INJECT(Bar(std::function(int)> myClassFactory)) {
- std::unique_ptr x = myClassFactory(15);
- ...
- }
- };
-
-
-
-
-
-Note the `fruit::Assisted<>` wrapping the type `int` where `registerFactory()` is called. This allows to distinguish
-types that should be parameters of the factory ("assisted injection", like `int` in this example) from ones that should
-be injected by Fruit (normal, non-assisted injection, like `Foo` in this example).
-
-While Fruit will only create one instance of the factory in each injector, every call to the factory potentially returns
-another value; Fruit does not memoize the return value. So two calls to `myClassFactory(15)` will return different
-instances.
-
-If memoization is desired, it can be performed in the lambda passed to `registerFactory()`.
-
-Also, for factories, Fruit does **not** take ownership of the values created by the factory. So it's preferable to
-return a `std::unique_ptr` in the lambda instead of a plain pointer to give ownership of the object to the caller of the
-factory.
-
-It's possible to bind factories using `bind<>`, see the [section on bind](quick-reference#bindings) for more info.
-
-In simple cases, where the lambda passed to `registerFactory()` just calls `std::unique_ptr(new MyClass(...))`
-(as in the example above) the `INJECT()` macro or an `Inject` typedef can be used in the created class itself, instead
-of writing the `registerFactory()` call explicitly in the component definition.
-
- class MyClass {
- public:
- INJECT(MyClass(Foo* foo, ASSISTED(int) n));
- ...
- };
-
-
-
-
-
-Note that when using `INJECT()` for assisted injection, the assisted types are wrapped with the `ASSISTED()` macro
-instead of `fruit::Assisted<>`.
-
- class MyClass {
- public:
- MyClass(Foo* foo, int n);
-
- using Inject = MyClass(Foo*, fruit::Assisted);
- ...
- };
-
-Instead, if an `Inject` typedef is used, the types that require assisted injection should be wrapped in
-`fruit::Assisted<>` (as in the original `registerFactory()` call) instead of `ASSISTED()`.
-
-In both cases, the constructor definition (in case the constructor is defined outside the class definition) does **not**
-need to wrap the types in any way; this is obvious when using the `Inject` typedef, but less obvious when using the
-`ASSISTED()` macro.
-
-The `INJECT()` macro (and the equivalent Inject typedef) can also be used to inject factories in the special case when
-there are 0 assisted arguments; in this case they will bind a type of the form
-`std::function()>` consistently with the cases with >0 assisted arguments.
-
-## Type of a component, components with requirements and automatic bindings
-
-When using Fruit, every component has a type that declares what type bindings the component exposes and which ones (if
-any) the component requires.
-
-For example, if a component has type `fruit::Component, U1, U2>`, that component exposes the
-types `U1` and `U2` but requires bindings for `T1`, `T2` and `T3`. In the common case where a component has no
-requirements, the `fruit::Required<...>` part can be omitted, so we would have just `fruit::Component` in this
-case.
-
-When combining components, requirements can be satisfied with a matching binding, or by installing a component that
-provides those types.
-
-For example:
-
- fruit::Component, U1, U2> getU1U2Component();
- fruit::Component, T1> getT1Component();
-
- class SomeType : public T2 {
- public:
- INJECT(SomeType(T3*)) {...}
- };
-
- fruit::Component, U1> getU1Component() {
- return fruit::createComponent()
- .install(getU1U2Component) // Now U1,U2 are provided, T1,T2,T3 are required
- .install(getT1Component) // Now U1,U2,T1 are provided, T2,T3 are required
- .bind(); // Now U1,U2,T1,T2 are provided,
- // T3,SomeType are required
- }
-
-
-
-
-
-When Fruit compares the provides/requires with the return type of the `getT1Component()` function, it realizes that all
-types declared to be provided are already provided, but the type `SomeType` is currently required even though it's not
-declared as required in the resulting Component. At this point Fruit looks for an `Inject` typedef in SomeType (the
-`INJECT()` macro is just a shorthand for an `Inject` typedef), finds it and adds the binding to the component (automatic
-binding). Note that in order to add the automatic binding Fruit needs to look at the class definition of `SomeType`.
-Instead, for other types (e.g. `T3`) Fruit doesn't require the definition, a forward declaration is enough to make the
-above function compile.
-
-When calculating the required and provided types, Fruit also ensures that there are no dependency loops between bindings
-and/or components. For example, the following code produces a (compile time) dependency loop error:
-
- fruit::Component, T1> getT1Component();
- fruit::Component, T2> getT2Component();
-
- fruit::Component getT1T2Component() {
- return fruit::createComponent()
- .install(getT1Component)
- .install(getT2Component); // Error, dependency loop.
- }
-
-
-
-
-
-## Injector
-
-A Fruit injector is an object of type `fruit::Injector`. Unlike components, injectors can't have
-requirements. The types `T1,...Tn` are the types exposed by the injector, i.e. the types that can be used in calls to
-`get<>`. Even though the injector most likely contains bindings for other types, only the types explicitly declared in
-the injector type can be directly obtained by the injector itself. Other types will be injected as needed using the
-bindings in the injector, but behind the scenes.
-
-Multibindings behave differently, see the [section on multibindings](quick-reference#multibindings) for more
-information.
-
-For each type `T` exposed by the injector, the following `get()` calls are allowed:
-
-* `injector.get()`
-* `injector.get()`
-* `injector.get()`
-* `injector.get()`
-* `injector.get()`
-* `injector.get>()`
-* `injector.get>()`
-* `injector.get>()`
-
-See the [section on lazy injection](quick-reference#lazy-injection) to see what `fruit::Provider` is; the other types
-should be clear.
-
-For constant bindings (e.g. the `T` in `fruit::Injector`) only the following `get()` calls are allowed:
-
-* `injector.get()`
-* `injector.get()`
-* `injector.get()`
-* `injector.get>()`
-
-Note that we don't mention any `std::function` here. This is because the injector treats `std::function` as any other
-type.
-
-If `T` is `std::function(T1,...Tn)>` the above get calls are allowed as for any other `T`. Note that
-those are allowed for the `std::function` type, but not for `X` itself.
-
-For convenience, the injector also has a conversion operator to all types that can be retrieved from it using `get()`.
-For example, this get call:
-
- MyClass* myClass = injector.get();
-
-can be abbreviated as:
-
- MyClass* myClass(injector);
-
-## Normalized components
-
-Normalized components are a feature of Fruit that allows for fast creation of multiple injectors that share most (or
-all) the bindings.
-
-This is an advanced feature of Fruit that allows to reduce injection time in some cases; if you're just starting to
-use Fruit you might want to ignore this for now (just construct an Injector from your root Component function).
-
-Using a NormalizedComponent only helps if:
-
-* You create multiple injectors during the lifetime of a process. E.g. if you only create one injector at startup you
- won't benefit from using `NormalizedComponent`.
-
-* Some of those injectors share all (or almost all) their bindings.
-
-When both of those requirements apply, you can switch to using `NormalizedComponent` in the "similar" injectors by
-first refactoring the injectors' root components to be of the form:
-
- fruit::Component<...> getRootComponent(...) {
- return fruit::createComponent()
- // This contains the bindings common to the group of similar injectors.
- .install(getSharedComponent, ...)
- // This contains the bindings specific to this injector.
- .install(getSpecificComponent, ...);
- }
-
-Then you can change your injector construction from:
-
- fruit::Injector<...> injector(getRootComponent, ...);
-
-To:
-
- fruit::NormalizedComponent, ...> normalized_component(getSharedComponent, ...);
- fruit::Injector<...> injector(normalized_component, getSpecificComponent, ...);
-
-This splits the work of constructing the Injector in two phases: normalization (where Fruit will call the `Component`
-functions to collect all the bindings and check for some classes of runtime errors) and the actual creation of the
-injector, during which Fruit will also collect/check the additional bindings specific to that injector.
-
-Then you can share the same normalized_component object across all those injectors (also in different threads,
-`NormalizedComponent` is thread-safe), so that the normalization step only occurs once (i.e., you should only construct
-`NormalizedComponent` from `getSharedComponent` once, otherwise you'd pay the normalization cost multiple times).
-
-Creating an `Injector` from a `NormalizedComponent` and injecting separate instances is very cheap, on the order of 2 us
-for an injection graph with 100 interfaces, 100 implementation classes and 900 edges (for more details see
-[the Benchmarks page](https://github.com/google/fruit/wiki/benchmarks)).
-
-This might (depending of course on your performance requirements) allow you to create injectors where it would
-otherwise be unthinkable, e.g. creating a separate injector for each request in a server.
-
-Injectors that share the same `NormalizedComponent` are still independent; for example, if you call
-`injector.get()` in two injectors, each injector will construct its own instance of `Foo`.
-
-Example usage:
-
- fruit::Component, X> getXComponent(); // Lots of bindings here
-
- int main() {
- fruit::NormalizedComponent, X> normalizedComponent(
- getXComponent());
-
- for (...) {
- fruit::Component yComponent = ...; // Few injector-specific bindings
-
- Injector injector(normalizedComponent, yComponent);
- X* x = injector.get();
- ...
- }
- }
-
-
-Constructing an injector from a `NormalizedComponent` is much faster than constructing it from a Component, because most
-of the processing (aka normalization) has been done in advance when the `Component` object was converted to
-`NormalizedComponent`. It's also possible to specify some additional bindings at the point where the injector is
-created; however, this should be limited to very few bindings (<5 is best, <10 is still ok). If too many of these
-bindings are added, the injector construction can become even slower than it would have been without using the
-normalized component.
-
-As mentioned before, normalized components are best suited if the vast majority of the bindings are common. A typical
-use case is in a server, where a separate injector is created for every request, but the bindings of the handler classes
-are common to all requests; in that case a normalized component can be used, and the request itself (and possibly some
-metadata about the request) can be added to each injector at the point of construction. See the
-[section on injection scopes](quick-reference#injection-scopes) for a more detailed example.
-
-## Injection scopes
-
-This section is meant for readers familiar with Guice. If you don't know what injection scopes are, feel free to skip
-this section.
-
-Unlike Guice, Fruit does **not** have injection scopes. However, Fruit's normalized components can be used in situations
-where with Guice you would have used injection scopes.
-
-As an example, let's consider a situation in which there are 3 scopes, with the types `X`, `Y` and `Z` part of the three
-scopes respectively:
-
- // Outer scope
- class X {
- public:
- INJECT(X()) = default;
- ...
- };
-
- fruit::Component getXComponent() {
- return fruit::createComponent();
- }
-
- // Middle scope
- class Y {
- public:
- INJECT(Y(X* x));
- ...
- };
-
- fruit::Component, Y> getYComponent() {
- return fruit::createComponent();
- }
-
- // Inner scope
- class Z {
- public:
- INJECT(Z(X* x, Y* y));
- ...
- };
-
- fruit::Component, Z> getZComponent() {
- return fruit::createComponent();
- }
-
-Then the code that creates the injectors can be written as:
-
- fruit::Component<> getEmptyComponent() {
- return fruit::createComponent();
- }
-
- fruit::Component getXInstanceComponent(X* x) {
- return fruit::createComponent()
- .bindInstance(*x);
- }
-
- fruit::Component getXYInstanceComponent(X* x, Y* y) {
- return fruit::createComponent()
- .bindInstance(*x)
- .bindInstance(*y);
- }
-
- fruit::NormalizedComponent outerScopeNormalizedComponent(
- getXComponent);
- fruit::NormalizedComponent, Y> middleScopeNormalizedComponent(
- getYComponent);
- fruit::NormalizedComponent, Z> innerScopeNormalizedComponent(
- getZComponent);
-
- for (...) {
- // We want to enter the outer scope here.
- fruit::Injector outerScopeInjector(
- outerScopeNormalizedComponent, getEmptyComponent);
- X* x = outerScopeInjector.get();
- for (...) {
- // We want to enter the middle scope here.
- fruit::Injector middleScopeInjector(
- middleScopeNormalizedComponent, getXInstanceComponent, x);
- Y* y = middleScopeInjector.get();
- for (...) {
- // We want to enter the inner scope here.
- fruit::Injector innerScopeInjector(
- innerScopeNormalizedComponent, getXYInstanceComponent, x, y);
- Z* z = innerScopeInjector.get();
- ...
- }
- }
- }
-
-The instance of `X` is owned by `outerScopeInjector` so it lives for a full iteration of the outer loop. The instance of
-`Y` is owned by `middleScopeInjector` so it lives for an iteration of the middle loop. Finally, the instance of `Z` is
-owned by `innerScopeInjector` so it only lives for an iteration of the inner loop.
-
-See the [section on normalized components](quick-reference#normalized-components) and the
-[section on bindInstance](quick-reference#binding-instances) if the code above is not clear.
-
-## Eager injection
-
-If you create an injector that will be used concurrently by multiple threads, you either need to synchronize the calls
-(using a lock) or you might want to inject everything to start with, so that all `get` and `getMultibindings` calls on
-the injector don't need to modify it (as the objects have already been constructed). The `Injector` class provides a
-method to do this: `eagerlyInjectAll()`. After calling this method, the `Injector` object can be shared by multiple
-threads with no locking.
-
-However, this does not perform lazy injection; so if you're only injecting a `Provider`, `Foo` will not be
-constructed. This means that even after calling this method, `get()` calls on `Provider` objects are still **not**
-thread-safe (unless you're sure that that class has already been injected).
-
-## Lazy injection
-
-Lazy injection is a feature that can be used when a type `Foo` depends on a type `Bar` only for some methods, and `Bar`
-is expensive to inject. This may not necessarily be because the `Bar` constructor is slow, it might be expensive because
-it triggers the injection of many other types. In this case, `Foo` can depend on `fruit::Provider` instead of
-directly depending on `Bar`. This delays the injection of `Bar` (and of the types that need to be injected in order to
-inject the `Bar` object) until the `get` method of the provider is called.
-
-Let's see some example code for this situation:
-
- class Bar {
- public:
- INJECT(Bar(ReallyExpensiveClass x, SomeOtherReallyExpensiveClass y));
- ...
- };
-
- class Foo {
- private:
- fruit::Provider barProvider;
-
- public:
- INJECT(Foo(fruit::Provider barProvider))
- : barProvider(barProvider) {
- }
-
- void doSomething() {
- Bar* bar = barProvider.get();
- ...
- }
- };
-
-`Bar`, `ReallyExpensiveClass` and `SomeOtherReallyExpensiveClass` are only injected when `foo->doSomething()` is called,
-not when `Foo` itself is injected. This can give a sizable performance win if `foo->doSomething()` is not always called.
-
-Every call to `get()` (within the same injector) returns the same `Bar` instance, and that's also the same instance that
-will be used to inject other classes (if there are other classes that depend on `Bar`).
-
-This means that the call to `get()` contains a branch (basically an `if (is_already_initialized) {...}`) so once the
-`Bar*` has been retrieved you might want to store it in a variable or field instead of calling `get()` multiple times.
-
-## Templated and parametrized components
-
-`get*Component()` functions are just normal functions; therefore they can be templated:
-
- template
- class FooInterface { ... };
-
- template
- class FooImpl : public FooInterface> {
- public:
- INJECT(FooImpl()) = default;
- ...
- };
-
- template
- fruit::Component> getFooComponent() {
- return createComponent()
- .bind>, FooImpl>();
- }
-
-
-
-
-
-And they can parametrized:
-
- class FooInterface { ... };
-
- class OldFooImpl : public FooInterface {
- public:
- INJECT(OldFooImpl()) = default;
- ...
- };
-
- class NewFooImpl : public FooInterface {
- public:
- INJECT(NewFooImpl()) = default;
- ...
- };
-
- fruit::Component getFooComponent(bool use_old_impl) {
- if (use_old_impl) {
- return fruit::createComponent()
- .bind();
- } else {
- return fruit::createComponent()
- .bind();
- }
- }
-
-
-
-
-
-The last example also shows how to do conditional injection.
-
-When parameterizing them, however, there are some constraints on the argument types. Specifically, they must be:
-
- * Copy-constructible
- * Move-constructible
- * Assignable
- * Move-assignable
- * Equality-comparable (i.e., `operator==` must be defined for two values of that type)
- * Hashable (i.e., `std::hash` must be defined for values of that type)
-
-Note that this only applies to the arguments of the function, not the types declared by the returned `Component`. In the
-example above, this means that `bool` must satisfy these requirements (and it does), but `FooInterface`, `NewFooImpl`
-and `OldFooImpl` don't need to.
diff --git a/Tutorial:-Annotated-injection.md b/Tutorial:-Annotated-injection.md
deleted file mode 100644
index 0374c7d..0000000
--- a/Tutorial:-Annotated-injection.md
+++ /dev/null
@@ -1,143 +0,0 @@
-
-In some situations several implementation types might have the same "natural interface" they implement, except that only
-one of these types can be bound to it within a single injector. For example, a car might have a main brake and an
-emergency brake, which both implement the same `Brake` interface.
-
-Intuitively, we'd want a component like:
-
- Component??> getBrakesComponent() {
- return fruit::createComponent()
- .bind()
- // This doesn't actually work, Brake is already bound
- .bind();
- }
-
-And a way to inject `MainBrakeImpl` and `EmergencyBrakeImpl` instead of just `Brake`. While it's of course possible to
-inject the two concrete classes, doing so requires including their definitions (that would otherwise be in the `.cpp`
-files that define the components) into all places that need to inject one or the other.
-
-Assisted injection is a feature of Fruit that helps with these situations (if you're familiar with Guice, this should
-sound familiar). Let's see how we can use it to solve this example. The full sources are available at
-[examples/annotated_injection](https://github.com/google/fruit/tree/master/examples/annotated_injection).
-
-Let's start with the `Brake` interface, which is straightforward (no sign of annotated injection yet):
-
- // brake.h
- class Brake {
- public:
- // Activates the brake. Throws an exception if braking failed.
- virtual void activate() = 0;
- };
-
-Then we can write an implementation of `Brake` marked as the main brake as follows:
-
- // main_brake.h
- struct MainBrake {};
-
- fruit::Component> getMainBrakeComponent();
-
-
-
- // main_brake.cpp
- class MainBrakeImpl : public Brake {
- public:
- INJECT(MainBrakeImpl()) = default;
-
- void activate() override {
- // ...
- }
- };
-
- fruit::Component> getMainBrakeComponent() {
- return fruit::createComponent()
- .bind, MainBrakeImpl>();
- }
-
-`fruit::Annotated` is a way to mark the type `Brake` with the "annotation" `MainBrake`. The annotation
-type can be any type, but to avoid confusion it's preferable to define a type just for this purpose, for example as an
-empty struct as we do here.
-
-Fruit accepts annotated types in many places. For example here we see it passed as a parameter to `Component` and
-`bind()`. Note that it's not necessary to annotate `MainBrakeImpl` too: there's only one binding of that type in the
-injector, and when binding types with `bind()` the two types don't need to have the same annotation. It would be
-possible though (it's just unnecessary in this case).
-
-We can then define an emergency brake class on the exact same way:
-
- // emergency_brake.h
- struct EmergencyBrake {};
-
- fruit::Component>
- getEmergencyBrakeComponent();
-
-
-
- // emergency_brake.cpp
- class EmergencyBrakeImpl : public Brake {
- public:
- INJECT(EmergencyBrakeImpl()) = default;
-
- void activate() override {
- // ...
- }
- };
-
- fruit::Component>
- getEmergencyBrakeComponent() {
-
- return fruit::createComponent()
- .bind, EmergencyBrakeImpl>();
- }
-
-We can then inject the two brakes in our `Car` class, as follows:
-
- // car.cpp
- class CarImpl : public Car {
- private:
- Brake* mainBrake;
- Brake* emergencyBrake;
-
- public:
- INJECT(CarImpl(ANNOTATED(MainBrake, Brake*) mainBrake,
- ANNOTATED(EmergencyBrake, Brake*) emergencyBrake))
- : mainBrake(mainBrake), emergencyBrake(emergencyBrake) {
- }
- // Or:
- // using Inject = CarImpl(fruit::Annotated,
- // fruit::Annotated);
- // CarImpl(Brake* mainBrake, Brake* emergencyBrake)
- // : mainBrake(mainBrake), emergencyBrake(emergencyBrake) {
- // }
-
- void brake() override {
- try {
- mainBrake->activate();
- } catch (...) {
- // The main brake failed!
- emergencyBrake->activate();
- }
- }
- };
-
- fruit::Component getCarComponent() {
- return fruit::createComponent()
- .bind()
- .install(getMainBrakeComponent)
- .install(getEmergencyBrakeComponent);
- }
-
-Note the use of the `ANNOTATED` macro inside `INJECT`, the equivalent `Inject` typedef, and the fact that the two
-parameters of the constructor are of type `Brake*` (i.e., `ANNOTATED` only adds the annotation to the parameter type in
-the `Inject` typedef, but not to the constructor parameter).
-
-In this case both parameters were marked with `ANNOTATED`, but it's of course possible to mix annotated parameters with
-non-annotated ones in the same class.
-
-This diagram models the Car component above:
-
-
-
-
-
-In the [next part of the tutorial](https://github.com/google/fruit/wiki/tutorial:-errors) we'll see how Fruit reports
-injection errors.
diff --git a/Tutorial:-Assisted-injection.md b/Tutorial:-Assisted-injection.md
deleted file mode 100644
index 1af2d2b..0000000
--- a/Tutorial:-Assisted-injection.md
+++ /dev/null
@@ -1,122 +0,0 @@
-
-In this part of the tutorial, we'll build a component that scales `double` values by a constant factor. The full source
-is available in [examples/scaling_doubles](https://github.com/google/fruit/tree/master/examples/scaling_doubles).
-To warm up, let's write a `Multiplier` component.
-
- // multiplier.h
- class Multiplier {
- public:
- // Returns the product of x and y.
- virtual double multiply(double x, double y) = 0;
- };
-
- fruit::Component getMultiplierComponent();
-
-
-
- // multiplier.cpp
- #include "multiplier.h"
-
- class MultiplierImpl : public Multiplier {
- public:
- double multiply(double x, double y) override {
- return x * y;
- }
- };
-
- fruit::Component getMultiplierComponent() {
- return fruit::createComponent()
- .bind()
- .registerConstructor();
- }
-
-
-
-
-
-When there is a canonical implementation of an interface, as in this case, we can put the definition of the interface
-and the `get*Component()` function declaration in the same header file, to avoid having two separate header files.
-
-Note that the `MultiplierImpl` constructor was _not_ wrapped with `INJECT()`. It's a convenient way to tell Fruit what
-injector to use, but it can't be used in some cases, for example if `MultiplierImpl` was provided by another project
-that doesn't use Fruit. Here we could use it, but we don't just to show the (equivalent) explicit `registerConstructor`
-call with the constructor signature.
-
- // scaler.h
- class Scaler {
- public:
- virtual double scale(double x) = 0;
- };
-
- using ScalerFactory = std::function(double)>;
-
- fruit::Component getScalerComponent();
-
-At first, one might be tempted to write `Component`. However, there is no single `Scaler` implementation, there
-is a `Scaler` for each `double` value (the scaling factor). So we expose this in the component signature. When returning
-a value type we can just return it by value, but for interfaces we must return a `unique_ptr`. Fruit can inject any
-class, but there is special support for types of the form `std::function(...)>` as we'll see shortly.
-Let's write the implementation now.
-
- // scaler.cpp
- #include "scaler.h"
- #include "multiplier.h"
-
- class ScalerImpl : public Scaler {
- private:
- Multiplier* multiplier;
- double factor;
-
- public:
- INJECT(ScalerImpl(ASSISTED(double) factor, Multiplier* multiplier))
- : multiplier(multiplier), factor(factor) {
- }
-
- double scale(double x) override {
- return multiplier->multiply(x, factor);
- }
- };
-
- fruit::Component getScalerComponent() {
- return fruit::createComponent()
- .bind()
- .install(getMultiplierComponent());
- }
-
-
-
-
-
-Here we see for the first time the use of the `ASSISTED()` macro. It's used to mark types in a constructor wrapped with
-`INJECT()` that don't have to be injected, but will become the parameters of an injected factory function.
-
-Note that here we installed the multiplier component directly, instead of declaring it as a requirement and then writing
-a component that composes `ScalerImplComponent` and `MultiplierComponent`. It's a tradeoff: this slightly reduces
-modularity, but makes the code more concise (it avoids 2 files). There is no definite answer on what's better; this
-tradeoff must be evaluated on a case-by-case basis.
-
-Note also that the `bind` operation now is doing something different: instead of binding `Scaler` to `ScalerImpl`, it's
-binding an `std::function(double)>` to a `std::function(double)>`,
-which is then injected using constructor injection.
-
- // main.cpp
- #include "scaler.h"
-
- int main() {
- fruit::Injector injector(getScalerComponent);
- ScalerFactory scalerFactory(injector);
-
- std::unique_ptr scaler = scalerFactory(12.1);
- std::cout << scaler->scale(3) << std::endl;
-
- return 0;
- }
-
-Here is the `main()` function, which should be easy to understand at this point. We get an instance of the factory from
-the injector, and then we call the factory ourselves to get an instance of `Scaler`.
-
-Now you know the basics of how to use Fruit. To get more familiar with it, try rewriting the above system by yourself or
-any other program that you like, and experiment a bit by changing the code.
-
-In the [next part of the tutorial](https://github.com/google/fruit/wiki/tutorial:-server) we'll see how to use Fruit to
-write a server.
diff --git a/Tutorial:-Errors.md b/Tutorial:-Errors.md
deleted file mode 100644
index 5cf002e..0000000
--- a/Tutorial:-Errors.md
+++ /dev/null
@@ -1,78 +0,0 @@
-
-One of the key features of Fruit is that errors are reported at compile time. However, these error messages might be
-confusing at first. In this part of the tutorial we'll learn how Fruit error messages look like and what are the
-important parts to look for.
-
-In this tutorial we'll see the error messages emitted by GCC (specifically, GCC 7.0.1). Clang error messages are
-similar.
-
-Let's consider this example:
-
- struct X {
- };
-
- fruit::Component getComponent() {
- return fruit::createComponent();
- }
-
-Here we expect an error, because `X` is not explicitly bound and can't be automatically bound because it has no
-constructor wrapped in `INJECT` nor an `Inject` typedef.
-
- In file included from /usr/local/include/fruit/fruit.h:25:0,
- from main.cpp:2:
- /usr/local/include/fruit/impl/injection_errors.h: In instantiation of ‘struct fruit::impl::NoBindingFoundError’:
- /usr/local/include/fruit/impl/component.defn.h:59:55: required from ‘fruit::Component::Component(fruit::PartialComponent) [with Bindings = {}; Params = {X}]’
- main.cpp:8:35: required from here
- /usr/local/include/fruit/impl/injection_errors.h:33:3: error: static assertion failed: No explicit binding nor C::Inject definition was found for T.
- static_assert(
- ^~~~~~~~~~~~~
- In file included from /usr/local/include/fruit/component.h:705:0,
- from /usr/local/include/fruit/fruit.h:28,
- from main.cpp:2:
- /usr/local/include/fruit/impl/component.defn.h: In instantiation of ‘fruit::Component::Component(fruit::PartialComponent) [with Bindings = {}; Params = {X}]’:
- main.cpp:8:35: required from here
- /usr/local/include/fruit/impl/component.defn.h:62:135: error: no type named ‘Result’ in ‘fruit::impl::meta::OpForComponent<>::ConvertTo, fruit::impl::meta::Vector >, fruit::impl::meta::Vector >, fruit::impl::meta::Vector, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> > {aka struct fruit::impl::meta::Error}’
- (void)typename fruit::impl::meta::CheckIfError>::type();
- ^~~~~~
- /usr/local/include/fruit/impl/component.defn.h:65:68: error: ‘using Op = fruit::impl::meta::OpForComponent<>::ConvertTo, fruit::impl::meta::Vector >, fruit::impl::meta::Vector >, fruit::impl::meta::Vector, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> > {aka struct fruit::impl::meta::Error}’ has no member named ‘numEntries’
- std::size_t num_entries = component.storage.numBindings() + Op().numEntries();
- ~~~~~^~~~~~~~~~
- /usr/local/include/fruit/impl/component.defn.h:68:7: error: no match for call to ‘(Op {aka fruit::impl::meta::Error}) (fruit::impl::FixedSizeVector&)’
- Op()(entries);
- ~~~~^~~~~~~~~
-
-When you receive Fruit error messages, you should only look at the first error. Different compilers have varying amount
-of success in reporting useful errors after the first one. So let's focus on the first error:
-
- In file included from /usr/local/include/fruit/fruit.h:25:0,
- from main.cpp:2:
- /usr/local/include/fruit/impl/injection_errors.h: In instantiation of ‘struct fruit::impl::NoBindingFoundError’:
- /usr/local/include/fruit/impl/component.defn.h:59:55: required from ‘fruit::Component::Component(fruit::PartialComponent) [with Bindings = {}; Params = {X}]’
- main.cpp:8:35: required from here
- /usr/local/include/fruit/impl/injection_errors.h:33:3: error: static assertion failed: No explicit binding nor C::Inject definition was found for T.
- static_assert(
- ^~~~~~~~~~~~~
-
-From here you can see that:
-
-* the error is a `NoBindingFoundError` for the type `X` (third line)
-* it was caused by `main.cpp:8`
-* The detailed error message is `No explicit binding nor C::Inject definition was found for T.`. Note that in this
- message, `T` refers to the type in the `*Error<>` instantiation (in this case, `T` is `X`).
-
-If we now change the code above to:
-
- struct X {
- INJECT(X()) = default;
- };
-
- fruit::Component getComponent() {
- return fruit::createComponent();
- }
-
-Then the file will compile.
-
-This is how Fruit reports missing bindings, one of the most common injection errors.
-
-In the [next part of the tutorial](https://github.com/google/fruit/wiki/tutorial:-assisted-injection) we'll learn how to
-use assisted injection.
diff --git a/Tutorial:-Getting-started.md b/Tutorial:-Getting-started.md
deleted file mode 100644
index 1e036b5..0000000
--- a/Tutorial:-Getting-started.md
+++ /dev/null
@@ -1,86 +0,0 @@
-Let's look at a simple example: a Hello world implementation written using Fruit. Using Fruit is probably overkill for
-such a simple situation, but it allows us to see the basic features and syntax of Fruit.
-
- #include
- #include
-
- class Writer {
- public:
- virtual void write(std::string s) = 0;
- };
-
- class StdoutWriter : public Writer {
- public:
- // Like "StdoutWriter() = default;" but also marks this constructor as the one to use for injection.
- INJECT(StdoutWriter()) = default;
-
- virtual void write(std::string s) override {
- std::cout << s;
- }
- };
-
- class Greeter {
- public:
- virtual void greet() = 0;
- };
-
- class GreeterImpl : public Greeter {
- private:
- Writer* writer;
-
- public:
- // Like "GreeterImpl(Writer* writer) : ... {...}" but also marks this constructor as the one to use for injection.
- INJECT(GreeterImpl(Writer* writer))
- : writer(writer) {
- }
-
- virtual void greet() override {
- writer->write("Hello world!\n");
- }
- };
-
- fruit::Component getGreeterComponent() {
- return fruit::createComponent()
- .bind()
- .bind();
- }
-
- int main() {
- fruit::Injector injector(getGreeterComponent);
- Greeter* greeter = injector.get();
- greeter->greet();
- return 0;
- }
-
-The structure of the above program can be modelled with the following component diagram.
-
-
-
-
-
-The `StdoutWriter` class requires nothing and provides a `StdoutWriter` instance. The binding between `StdoutWriter` and
-`Writer` requires a `StdoutWriter` instance and provides a `Writer` instance. The `GreeterImpl` class requires a
-`Writer` instance and provides a `GreeterImpl` instance. The binding between `GreeterImpl` and `Greeter` requires a
-`GreeterImpl` instance and provides a `Greeter` instance. Finally, `GreeterComponent` requires nothing and provides a
-`Greeter` instance.
-
-When using Fruit, composite components are typically defined in a `get*Component()` function that starts by creating an
-empty component with a call to `fruit::createComponent()`, then uses a chain of operations to add sub-components. Here
-we only see the `bind()` operation but there are several more. The result of the chain of operations is then
-converted with an implicit conversion to the desired component type (in this case, `Component`); during this
-conversion Fruit looks for constructors in the bound classes that are wrapped in `INJECT()` and this is how the other
-two components above were added. Note that a component does _not_ have to expose all bound interfaces, for example in
-this case we haven't exposed the `Writer` interface, and we haven't exposed any implementation classes. An alternative
-signature for `getGreeterComponent()` that returns a `Component` would also
-be allowed.
-
-It's usually useful to hide information on concrete classes, so when a class is bound to an interface the implementation
-class is usually not provided. For simplicity, in the rest of the tutorial we'll model the component of the
-implementation class together with all the relevant bindings as a single component. The above diagram will then become:
-
-
-
-
-
-In the [next part of the tutorial](https://github.com/google/fruit/wiki/tutorial:-simple-system) we'll see a simple
-system built using Fruit.
diff --git a/Tutorial:-Server.md b/Tutorial:-Server.md
deleted file mode 100644
index b8040ef..0000000
--- a/Tutorial:-Server.md
+++ /dev/null
@@ -1,375 +0,0 @@
-
-In this chapter of the tutorial, we will see how to use Fruit's normalized components to write an HTTP-like server. We
-want to write a "server" that reads request URLs from standard input, and dispatches the request to the right handler
-based on the URL, handling each request in a separate thread.
-
-The full source is available in [examples/server](https://github.com/google/fruit/tree/master/examples/server).
-
-First, let's define the `Request` type. For this simple server, a request is just a URL.
-
- // request.h
- struct Request {
- std::string path;
- };
-
-We'll also have a `ServerContext` struct, to show how request handlers can access non-request-specific information.
-
-This class is not strictly necessary in our case, but we still use it to show how such information would be passed to
-the handlers in a real server.
-
- // server_context.h
- struct ServerContext {
- std::string startupTime;
- };
-
-Now let's write two request handlers: one for URLs starting with `/foo/`:
-
- // foo_handler.h
- #include "request.h"
- #include "server_context.h"
-
- class FooHandler {
- public:
- // Handles a request for a subpath of "/foo/".
- // The request is injected, no need to pass it directly here.`
- virtual void handleRequest() = 0;
- };
-
- fruit::Component, FooHandler>
- getFooHandlerComponent();
-
-
-
- // foo_handler.cpp
- #include "foo_handler.h"
-
- class FooHandlerImpl : public FooHandler {
- private:
- const Request& request;
- const ServerContext& serverContext;
-
- public:
- INJECT(FooHandlerImpl(const Request& request, const ServerContext& serverContext))
- : request(request), serverContext(serverContext) {
- }
-
- void handleRequest() override {
- cout << "FooHandler handling request on server started at "
- << serverContext.startupTime << " for path: " << request.path << endl;
- }
- };
-
- fruit::Component, FooHandler> getFooHandlerComponent() {
- return fruit::createComponent()
- .bind();
- }
-
-
-
-
-
-And, as you might have expected, one for URLs starting with `/bar/`:
-
- // bar_handler.h
- #include "request.h"
- #include "server_context.h"
-
- class BarHandler {
- public:
- // Handles a request for a subpath of "/bar/".
- // The request is injected, no need to pass it directly here.
- virtual void handleRequest() = 0;
- };
-
- fruit::Component, BarHandler>
- getBarHandlerComponent();
-
-
-
- // bar_handler.cpp
- #include "bar_handler.h"
-
- class BarHandlerImpl : public BarHandler {
- private:
- const Request& request;
- const ServerContext& serverContext;
-
- public:
- INJECT(BarHandlerImpl(const Request& request, const ServerContext& serverContext))
- : request(request), serverContext(serverContext) {
- }
-
- void handleRequest() override {
- cout << "BarHandler handling request on server started at "
- << serverContext.startupTime << " for path: " << request.path << endl;
- }
- };
-
- fruit::Component, BarHandler> getBarHandlerComponent() {
- return fruit::createComponent()
- .bind();
- }
-
-
-
-
-
-The interfaces of the two components require a `Request` and a `ServerContext` to be bound externally. This approach is
-more flexible than just passing them as parameter to `handleRequest()` for two reasons: first, the `FooHandler` and
-`BarHandler` interfaces don't need to depend on `ServerContext`. Also, this allows them to inject other classes that
-require `Request` and `ServerContext`, not just to inject `Request` and `ServerContext` themselves.
-
-Now we need a class that dispatches the requests to the right handler:
-
- // request_dispatcher.h
- #include "request.h"
- #include "server_context.h"
-
- class RequestDispatcher {
- public:
- // Handles the current request.
- // The request is injected, no need to pass it directly here.
- virtual void handleRequest() = 0;
- };
-
- fruit::Component, RequestDispatcher>
- getRequestDispatcherComponent();
-
-
-
- // request_dispatcher.cpp
- #include "request_dispatcher.h"
-
- #include "foo_handler.h"
- #include "bar_handler.h"
-
- class RequestDispatcherImpl : public RequestDispatcher {
- private:
- const Request& request;
- Provider fooHandler;
- Provider barHandler;
-
- public:
- INJECT(RequestDispatcherImpl(
- const Request& request,
- Provider fooHandler,
- Provider barHandler))
- : request(request),
- fooHandler(fooHandler),
- barHandler(barHandler) {
- }
-
- void handleRequest() override {
- if (stringStartsWith(request.path, "/foo/")) {
- fooHandler.get()->handleRequest();
- } else if (stringStartsWith(request.path, "/bar/")) {
- barHandler.get()->handleRequest();
- } else {
- cerr << "Error: no handler found for request path: '"
- << request.path << "' , ignoring request." << endl;
- }
- }
-
- private:
- static bool stringStartsWith(const string& s, const string& candidatePrefix) {
- return s.compare(0, candidatePrefix.size(), candidatePrefix) == 0;
- }
- };
-
- fruit::Component, RequestDispatcher>
- getRequestDispatcherComponent() {
-
- return fruit::createComponent()
- .bind()
- .install(getFooHandlerComponent)
- .install(getBarHandlerComponent);
- }
-
-
-
-
-
-Note that `RequestDispatcherImpl` holds providers of the handlers, not instances. This delays the injection of
-`FooHandler` and `BarHandler` to the point of use (when we call `get()` on the injector).
-
-We do this because we only want to inject the handler that is actually used for the request.
-In a large system, there will likely be many handlers, and many of those will have lots of dependencies that would also
-end up being injected if we injected all handler classes directly in `RequestDispatcherImpl` instead of injecting
-`Provider`s.
-
-And now we just need the `Server` class:
-
- // server.h
- #include "request.h"
- #include "server_context.h"
- #include "request_dispatcher.h"
-
- class Server {
- public:
- virtual void run(fruit::Component,
- RequestDispatcher>
- (*)()) = 0;
- };
-
- fruit::Component getServerComponent();
-
-Note that the `run()` method of the server takes a `Component` function. This is because we will use two injectors - one
-for the server startup (that will be used to inject the `Server` instance) and one for each request, that will be used
-to inject the request dispatcher.
-
-
-
-
-
- // server.cpp
- #include "server.h"
-
- #include "server_context.h"
- #include "request_dispatcher.h"
-
- class ServerImpl : public Server {
- private:
- std::vector threads;
-
- public:
- INJECT(ServerImpl()) {
- }
-
- ~ServerImpl() {
- for (std::thread& t : threads) {
- t.join();
- }
- }
-
- void run(fruit::Component,
- RequestDispatcher>
- (*getRequestDispatcherComponent)())
- override {
- ServerContext serverContext;
- serverContext.startupTime = getTime();
-
- const fruit::NormalizedComponent, RequestDispatcher>
- requestDispatcherNormalizedComponent(
- getRequestDispatcherComponentWithContext,
- getRequestDispatcherComponent,
- &serverContext);
-
- cerr << "Server started." << endl;
-
- while (1) {
- cerr << endl;
- cerr << "Enter the request (absolute path starting with \"/foo/\" or "
- << "\"/bar/\"), or an empty line to exit." << endl;
- Request request;
- getline(cin, request.path);
- cerr << "Server received request: " + request.path << endl;
- if (request.path.empty()) {
- cerr << "Server received empty line, shutting down." << endl;
- break;
- }
-
- threads.push_back(std::thread(
- worker_thread_main,
- std::ref(requestDispatcherNormalizedComponent), request));
- }
- }
-
- private:
- static void worker_thread_main(
- const fruit::NormalizedComponent<
- fruit::Required,
- RequestDispatcher>&
- requestDispatcherNormalizedComponent,
- Request request) {
-
- fruit::Injector injector(
- requestDispatcherNormalizedComponent, getRequestComponent, &request);
-
- RequestDispatcher* requestDispatcher(injector);
- requestDispatcher->handleRequest();
- }
-
- static string getTime() {
- time_t now = time(nullptr);
- tm* localTime = localtime(&now);
- string result = asctime(localTime);
- if (result.size() != 0 && result.back() == '\n') {
- result.pop_back();
- }
- return result;
- }
-
- static fruit::Component getRequestComponent(Request* request) {
- return fruit::createComponent()
- .bindInstance(*request);
- }
-
- static fruit::Component, RequestDispatcher>
- getRequestDispatcherComponentWithContext(
- fruit::Component, RequestDispatcher>(
- *getRequestDispatcherComponent)(),
- ServerContext* serverContext) {
- return fruit::createComponent()
- .install(getRequestDispatcherComponent)
- .bindInstance(*serverContext);
- }
- };
-
- fruit::Component getServerComponent() {
- return fruit::createComponent()
- .bind();
- }
-
-
-
-
-
-The `run()` method is a main-like method that is called at startup and will only terminate when the server is shut down.
-
-For every request (i.e. a line read from standard input) a new worker thread is created. `worker_thread_main()` creates
-the injector that will handle the request and calls `RequestDispatcher` to determine the correct handler.
-Note the use of `NormalizedComponent` instead of `Component` here. A normalized component is a transformed version of a
-component from which it's very efficient to create an injector; most of the computation that would otherwise take place
-when the injector is created is done in advance when the `NormalizedComponent` is created. In this example, this allows
-the server to do that computation only once, at startup, instead of repeating it in every request.
-
-It's still allowed to add some bindings to a `NormalizedComponent` before creating an injector. This is what happens in
-`worker_thread_main()`, that has to bind a different `Request` in each injector. The two-argument constructor of
-`Injector` takes a `NormalizedComponent` and a `Component` and creates an injector with the union of the bindings.
-Creating an injector for each request is faster than you might expect; look at
-[the benchmarks page](https://sites.google.com/site/fruitlib/benchmarks) for the details.
-
-Finally, we have the `main()` function, that creates the outer injector and calls `Server::run()`.
-
- // main.cpp
- #include "server.h"
- #include "request_dispatcher.h"
-
- int main() {
- Injector injector(getServerComponent);
-
- Server* server(injector);
- server->run(getRequestDispatcherComponent);
-
- return 0;
- }
-
-These are the dependencies between the source files:
-
-
-
-
-
-Note that changes to a handler (say, `bar_handler.cpp`) only require recompilation of that translation unit. When adding
-a handler, we need to recompile the new handler and `request_dispatcher.cpp` (that will likely need changes anyway); we
-still don't need to recompile the server nor the other handlers, as there's no dependency from `main.cpp` and
-`server.cpp` to the handlers, not even to their header files.
-
-This concludes the tutorial. Now you should be able to use Fruit effectively.
-
-For more details on each feature of Fruit, see the [Quick reference](quick-reference) or the [FAQ](faq). If something is
-still unclear, don't hesitate to [send me an email](mailto:poletti.marco@gmail.com).
-
-
-
-
diff --git a/Tutorial:-Simple-system.md b/Tutorial:-Simple-system.md
deleted file mode 100644
index 0a5fa66..0000000
--- a/Tutorial:-Simple-system.md
+++ /dev/null
@@ -1,293 +0,0 @@
-
-In this second part of the tutorial we'll implement a simple command line utility that reads a number and outputs the
-number incremented by 1. In a real-world system such a simple functionality would be in a single class (or even all in
-`main()`). Here we instead (over)use dependency injection to split functionality as much as possible, showing how Fruit
-can help building a complex system from several components, while limiting the dependencies between components.
-
-In the following, we omit the parts of the code that are not relevant (e.g. include guards, system includes). The full
-source is available in
-[examples/simple_injection](https://github.com/google/fruit/tree/master/examples/simple_injection).
-
-We start by writing the interface for the increment:
-
- // incrementer.h
- class Incrementer {
- public:
- // Returns x + 1.
- virtual int increment(int x) = 0;
- };
-
-An increment is a special case of addition, so let's also write an interface for a class that does addition:
-
- // adder.h
- class Adder {
- public:
- // Returns the sum of x and y.
- virtual int add(int x, int y) = 0;
- };
-
-Now we want a component that, given an implementation of `Adder`, provides an implementation of `Incrementer`.
-
- // incrementer_impl.h
- #include "incrementer.h"
- #include "adder.h"
-
- fruit::Component, Incrementer> getIncrementerImplComponent();
-
- // incrementer_impl.cpp
- #include "incrementer_impl.h"
-
- class IncrementerImpl : public Incrementer {
- private:
- Adder* adder;
-
- public:
- INJECT(IncrementerImpl(Adder* adder))
- : adder(adder) {
- }
-
- virtual int increment(int x) override {
- return adder->add(x, 1);
- }
- };
-
- fruit::Component, Incrementer> getIncrementerImplComponent() {
- return fruit::createComponent()
- .bind();
- }
-
-
-
-
-
-This is our first encounter with a component that has requirements. A Fruit component can have required types, and these
-types are specified using `fruit::Required` as the first type argument of a component. If the signature of
-`getIncrementerImplComponent()` didn't specify the requirement, Fruit would have looked for a binding for `Adder` and,
-not finding it, it would have aborted the compilation with an error. All required types that a component doesn't bind
-must be declared in the `Component` type.
-
-Note that the only information exposed in the header file is what the module requires and provides. The
-`IncrementerImpl` class is defined in the .cpp file only. This is similar to what happens using the
-[Pimpl idiom](http://en.wikipedia.org/wiki/Pimpl).
-
-Side note: some readers might have expected an anonymous namespace wrapping the implementation class. Adding it is
-reasonable, as the class is only used within the .cpp file. We have omitted the anonymous namespace here to make the
-code easier to understand.
-
-The lack of virtual destructors is also intended, as Fruit handles the destruction of the objects in the injector, and
-it destroys the concrete classes directly (not through a pointer to the base class), so the compiler will report no
-warnings (not even with `-W -Wall`). However you can still have a virtual destructor if you want to.
-
-Now, let's implement `Adder`.
-
- // simple_adder.h
- #include "adder.h"
-
- fruit::Component getSimpleAdderComponent();
-
- // simple_adder.cpp
- #include "simple_adder.h"
-
- class SimpleAdder : public Adder {
- public:
- INJECT(SimpleAdder()) = default;
-
- virtual int add(int x, int y) override {
- return x + y;
- }
- };
-
- fruit::Component getSimpleAdderComponent() {
- return fruit::createComponent()
- .bind();
- }
-
-
-
-
-
-This component is very simple, it should be self-explanatory at this point.
-
-So, we have a component that provides `Adder` and one that requires `Adder` and provides `Incrementer`. Now we want to
-combine the two.
-
- // simple_incrementer.h
- #include "incrementer.h"
-
- fruit::Component getSimpleIncrementerComponent();
-
- // simple_incrementer.cpp
- #include "simple_incrementer.h"
-
- #include "incrementer_impl.h"
- #include "simple_adder.h"
-
- fruit::Component getSimpleIncrementerComponent() {
- return fruit::createComponent()
- .install(getIncrementerImplComponent)
- .install(getSimpleAdderComponent);
- }
-
-
-
-
-
-`install()` is an operation that is used to "install" a sub-component inside the current component. As we've already
-seen in the previous page of the tutorial, note that here we are not exposing all the interfaces that we could. The
-`Adder` interface is considered an implementation detail, so we don't want to expose it. Note that it's not even
-included in the header file, only the .cpp file depends on it (indirectly, through `simple_adder.h`). This is an example
-of how Fruit helps reduce the number of includes (and therefore also the compilation time) of large projects. Without
-dependency injection, in order to expose an implementation of `Incrementer` we would have included `IncrementerImpl`,
-and the `IncrementerImpl` implementation would have included `SimpleAdder`. With dependency injection but without Fruit,
-the `IncrementerImpl` implementation would no longer include `SimpleAdder`, but the client code (e.g. `main()`) would
-have to include both `IncrementerImpl` and `SimpleAdder`.
-
-Phew! So much for incrementing a number.
-
-Now that the implementation part is complete, we just need to write the `main()` function.
-
- #include "simple_incrementer.h"
-
- int main() {
- fruit::Injector injector(getSimpleIncrementerComponent);
- Incrementer* incrementer = injector.get();
-
- int x;
- std::cin >> x;
- std::cout << incrementer->increment(x) << std::endl;
-
- return 0;
- }
-
-We construct an `Injector` from the component function, then get an instance of `Incrementer` from the injector. No need
-to include any class definition here, besides `Incrementer` itself.
-
-After releasing the above program with a hefty price tag (or open-source, depending on your taste :-) ) we get some
-customer feedback. Some customers are happy but some noticed that incrementing a big number sometimes yields a negative
-number. They would like us to add a `--checked` option that enables overflow checking.
-
-Our implementation code is modular (thanks to dependency injection), so we don't need to modify any of the above
-components. Also, the `Incrementer` component delegates the work to `Adder`, so the only thing that we need is a checked
-implementation of `Adder`.
-
- // checked_adder.h
- #include "adder.h"
-
- fruit::Component getCheckedAdderComponent();
-
- // checked_adder.cpp
- #include "checked_adder.h"
-
- class CheckedAdder : public Adder {
- private:
- bool add_overflows(int x, int y) {
- ... // Implementation here
- }
-
- public:
- INJECT(CheckedAdder()) = default;
-
- virtual int add(int x, int y) override {
- if (add_overflows(x, y)) {
- std::cerr << "CheckedAdder: detected overflow during addition of "
- << x << " and " << y << std::endl;
- abort();
- }
- return x + y;
- }
- };
-
- fruit::Component getCheckedAdderComponent() {
- return fruit::createComponent()
- .bind();
- }
-
-
-
-
-
-
-Nothing new here. Now we assemble the new component with the `IncrementComponent` that we've written before.
-
- // checked_incrementer.h
- #include "incrementer.h"
-
- fruit::Component getCheckedIncrementerComponent();
-
- // checked_incrementer.cpp
- #include "checked_incrementer.h"
- #include "incrementer_impl.h"
- #include "checked_adder.h"
-
- fruit::Component getCheckedIncrementerComponent() {
- return fruit::createComponent()
- .install(getIncrementerImplComponent)
- .install(getCheckedAdderComponent);
- }
-
-
-
-
-
-Except the reuse of the same `IncrementerComponent`, there's nothing interesting to note here.
-
- // incrementer_component.h
- #include "incrementer.h"
-
- fruit::Component getIncrementerComponent(bool checked);
-
- // incrementer_component.cpp
- #include "incrementer_component.h"
- #include "simple_incrementer.h"
- #include "checked_incrementer.h"
-
- fruit::Component getIncrementerComponent(bool checked) {
- if (checked) {
- return fruit::createComponent()
- .install(getCheckedIncrementerComponent);
- } else {
- return fruit::createComponent()
- .install(getSimpleIncrementerComponent);
- }
- }
-
-
-
-
-
-A `get*Component()` function is just a normal function, so we can have parameterized components just by adding
-parameters and we can do conditional injection by using an `if` inside the function and having multiple returns.
-
-Let's now rewrite `main()` to accept the new argument and to use the new parametrized component.
-
- // main.cpp
- #include "incrementer_component.h"
-
- using fruit::Component;
- using fruit::Injector;
-
- // Try e.g.:
- // echo 5 | ./incrementer
- // echo 2147483647 | ./incrementer
- // echo 2147483647 | ./incrementer --checked
- int main(int argc, const char* argv[]) {
- bool checked = false;
- if (argc == 2 && std::string(argv[1]) == "--checked")
- checked = true;
-
- Injector injector(getIncrementerComponent, checked);
- Incrementer* incrementer(injector);
-
- int x;
- std::cin >> x;
- std::cout << incrementer->increment(x) << std::endl;
-
- return 0;
- }
-
-Here we see an alternative syntax for obtaining a class instance from an injector. Instead of calling `get` on the
-injector, we convert the injector to the type that we want. This is convenient to avoid repeating the type twice
-(compare with the main function above).
-
-In the [next part of the tutorial](https://github.com/google/fruit/wiki/tutorial:-annotated-injection) we'll learn how
-to use annotated injection.
diff --git a/_Sidebar.md b/_Sidebar.md
deleted file mode 100644
index f8e20a9..0000000
--- a/_Sidebar.md
+++ /dev/null
@@ -1,12 +0,0 @@
-* [Home](home)
-* [Benchmarks](benchmarks)
-* [FAQ](faq)
-* [Install](install)
-* [Quick reference](quick-reference)
-* Tutorial
- * [Getting started](https://github.com/google/fruit/wiki/tutorial:-getting-started)
- * [Simple system](https://github.com/google/fruit/wiki/tutorial:-simple-system)
- * [Annotated injection](https://github.com/google/fruit/wiki/tutorial:-annotated-injection)
- * [Errors](https://github.com/google/fruit/wiki/tutorial:-errors)
- * [Assisted injection](https://github.com/google/fruit/wiki/tutorial:-assisted-injection)
- * [Server](https://github.com/google/fruit/wiki/tutorial:-server)
diff --git a/bar_handler.png b/bar_handler.png
deleted file mode 100644
index a931223..0000000
Binary files a/bar_handler.png and /dev/null differ
diff --git a/bind.png b/bind.png
deleted file mode 100644
index a777551..0000000
Binary files a/bind.png and /dev/null differ
diff --git a/bind_instance.png b/bind_instance.png
deleted file mode 100644
index 7ad3ce9..0000000
Binary files a/bind_instance.png and /dev/null differ
diff --git a/car_component.png b/car_component.png
deleted file mode 100644
index 6057e2c..0000000
Binary files a/car_component.png and /dev/null differ
diff --git a/checked_adder.png b/checked_adder.png
deleted file mode 100644
index e659624..0000000
Binary files a/checked_adder.png and /dev/null differ
diff --git a/checked_incrementer.png b/checked_incrementer.png
deleted file mode 100644
index 4e02a70..0000000
Binary files a/checked_incrementer.png and /dev/null differ
diff --git a/component_composition.png b/component_composition.png
deleted file mode 100644
index 9180cd9..0000000
Binary files a/component_composition.png and /dev/null differ
diff --git a/component_dep_loop.png b/component_dep_loop.png
deleted file mode 100644
index 16e8b95..0000000
Binary files a/component_dep_loop.png and /dev/null differ
diff --git a/foo_handler.png b/foo_handler.png
deleted file mode 100644
index afa4314..0000000
Binary files a/foo_handler.png and /dev/null differ
diff --git a/greeter.png b/greeter.png
deleted file mode 100644
index 7a7c065..0000000
Binary files a/greeter.png and /dev/null differ
diff --git a/hello_world-deps.png b/hello_world-deps.png
deleted file mode 100644
index c5a164c..0000000
Binary files a/hello_world-deps.png and /dev/null differ
diff --git a/incrementer.png b/incrementer.png
deleted file mode 100644
index 4dd4a88..0000000
Binary files a/incrementer.png and /dev/null differ
diff --git a/incrementer_component.png b/incrementer_component.png
deleted file mode 100644
index 1cc427b..0000000
Binary files a/incrementer_component.png and /dev/null differ
diff --git a/inject_macro.png b/inject_macro.png
deleted file mode 100644
index 86e3ab8..0000000
Binary files a/inject_macro.png and /dev/null differ
diff --git a/inject_macro_no_args.png b/inject_macro_no_args.png
deleted file mode 100644
index 63f71d1..0000000
Binary files a/inject_macro_no_args.png and /dev/null differ
diff --git a/inject_macro_template.png b/inject_macro_template.png
deleted file mode 100644
index f4f58bf..0000000
Binary files a/inject_macro_template.png and /dev/null differ
diff --git a/inject_typedef_greeter.png b/inject_typedef_greeter.png
deleted file mode 100644
index 86e3ab8..0000000
Binary files a/inject_typedef_greeter.png and /dev/null differ
diff --git a/inject_typedef_templated_constructor.png b/inject_typedef_templated_constructor.png
deleted file mode 100644
index 86e3ab8..0000000
Binary files a/inject_typedef_templated_constructor.png and /dev/null differ
diff --git a/inject_typedef_writer.png b/inject_typedef_writer.png
deleted file mode 100644
index 63f71d1..0000000
Binary files a/inject_typedef_writer.png and /dev/null differ
diff --git a/inject_typedef_writer2.png b/inject_typedef_writer2.png
deleted file mode 100644
index 63f71d1..0000000
Binary files a/inject_typedef_writer2.png and /dev/null differ
diff --git a/multibindings-deps.png b/multibindings-deps.png
deleted file mode 100644
index c5a164c..0000000
Binary files a/multibindings-deps.png and /dev/null differ
diff --git a/multiplier.png b/multiplier.png
deleted file mode 100644
index a3df4d1..0000000
Binary files a/multiplier.png and /dev/null differ
diff --git a/parametrized_component.png b/parametrized_component.png
deleted file mode 100644
index c96c4e3..0000000
Binary files a/parametrized_component.png and /dev/null differ
diff --git a/provider.png b/provider.png
deleted file mode 100644
index 5ef808e..0000000
Binary files a/provider.png and /dev/null differ
diff --git a/provider_functor.png b/provider_functor.png
deleted file mode 100644
index dbf5cd5..0000000
Binary files a/provider_functor.png and /dev/null differ
diff --git a/register_constructor.png b/register_constructor.png
deleted file mode 100644
index 5199027..0000000
Binary files a/register_constructor.png and /dev/null differ
diff --git a/register_constructor_component.png b/register_constructor_component.png
deleted file mode 100644
index a25629e..0000000
Binary files a/register_constructor_component.png and /dev/null differ
diff --git a/register_factory.png b/register_factory.png
deleted file mode 100644
index 251763b..0000000
Binary files a/register_factory.png and /dev/null differ
diff --git a/register_factory_macro.png b/register_factory_macro.png
deleted file mode 100644
index ae8837e..0000000
Binary files a/register_factory_macro.png and /dev/null differ
diff --git a/register_factory_use.png b/register_factory_use.png
deleted file mode 100644
index 2ad24a9..0000000
Binary files a/register_factory_use.png and /dev/null differ
diff --git a/request_dispatcher.png b/request_dispatcher.png
deleted file mode 100644
index f3aed89..0000000
Binary files a/request_dispatcher.png and /dev/null differ
diff --git a/request_injector.png b/request_injector.png
deleted file mode 100644
index 9d5562b..0000000
Binary files a/request_injector.png and /dev/null differ
diff --git a/scaler.png b/scaler.png
deleted file mode 100644
index 97a2456..0000000
Binary files a/scaler.png and /dev/null differ
diff --git a/scaling_doubles-deps.png b/scaling_doubles-deps.png
deleted file mode 100644
index 5a1e16e..0000000
Binary files a/scaling_doubles-deps.png and /dev/null differ
diff --git a/server-deps.png b/server-deps.png
deleted file mode 100644
index a47c0a3..0000000
Binary files a/server-deps.png and /dev/null differ
diff --git a/server.png b/server.png
deleted file mode 100644
index 283624e..0000000
Binary files a/server.png and /dev/null differ
diff --git a/simple_adder.png b/simple_adder.png
deleted file mode 100644
index fe1f371..0000000
Binary files a/simple_adder.png and /dev/null differ
diff --git a/simple_greeter.png b/simple_greeter.png
deleted file mode 100644
index fe54e84..0000000
Binary files a/simple_greeter.png and /dev/null differ
diff --git a/simple_incrementer.png b/simple_incrementer.png
deleted file mode 100644
index 64dcf68..0000000
Binary files a/simple_incrementer.png and /dev/null differ
diff --git a/simple_injection-deps.png b/simple_injection-deps.png
deleted file mode 100644
index 0de3c16..0000000
Binary files a/simple_injection-deps.png and /dev/null differ
diff --git a/templated_component.png b/templated_component.png
deleted file mode 100644
index 3094d9e..0000000
Binary files a/templated_component.png and /dev/null differ