Boost logo

Boost :

Subject: Re: [boost] Is there any interest in a dependency injection library?
From: Kris (krzysztof_at_[hidden])
Date: 2014-08-04 08:12:53


Hi Sohail,

As far as I understand the whole idea is to have one module which will be
able to create app on it owns and second
module which will have other bindings required. And, of course, both modules
should be separately compiled.
I implemented the example you have introduced according to given assumptions
and think I have managed to meet the requirements, but we shall see.
So, the whole idea is simple:

    * module1
        * in order to be able to create app binding for this/that is
required
        * provides interface to create app which will be separately compiled

    * module2
        * provides binging to module1 which will use it to create app
        * [optional] provides any other bindings

    * main
        * creates injector with module2 and creates app - knowledge of app
is not required, is hidden in modules cpp files

So, to make the example a bit more complex, let's say we have object world,
which require app and some other stuff.

struct world {
    world(std::unique_ptr<app>, std::shared_ptr<other_stuff>);
};

Right now to create world we only need to recompile module2.

auto injector = di::make_injector(module2());
(void)injector.create<world>();

which is the true for all headers provided, since all the implementation is
in cpp files.

///////////////////////////////////////-> start here

// things.hpp
#ifndef THINGS_ZIPI1EVE
#define THINGS_ZIPI1EVE

struct thing1 {};
struct thing2 {};

#endif

// this.hpp
#ifndef THIS_U2KTF9DP
#define THIS_U2KTF9DP

struct this_ {
    virtual ~this_() { }
    virtual void whatever() = 0;
};

#endif

// that.cpp
#include "that.hpp"

that::that(std::unique_ptr<thing1>, std::unique_ptr<thing2>) { }
void that::whatever() { }

// that.hpp
#ifndef THAT_LPR4I07J
#define THAT_LPR4I07J

#include <memory>
#include "this.hpp"
#include "things.hpp"

struct that : public this_ {
    that(std::unique_ptr<thing1>, std::unique_ptr<thing2>);
    void whatever() override;
};

#endif

// app.hpp
#ifndef APP_P3WNIP9Z
#define APP_P3WNIP9Z

#include <memory>

class this_;

struct app {
    app(std::unique_ptr<this_>);
};

#endif

// app.cpp
#include "app.hpp"
#include "this.hpp"

app::app(std::unique_ptr<this_>) { }

#endif

// module.hpp
#ifndef MODULE_UNMB1JJ2
#define MODULE_UNMB1JJ2

#include <boost/di.hpp>

namespace di = boost::di;

class that;

class module {
    using injector = di::injector<
        di::deduce<that> // or di::bind<this_, that>
>;

public:
    injector configure() const;

    template<typename T>
    T create();
};

#endif

// module.cpp
#include "module.hpp"
#include "that.hpp"
#include "app.hpp"

module::injector module::configure() const {
    return injector(); // runtime values binding not required
}

template<>
std::shared_ptr<app> module::create<std::shared_ptr&lt;app>>() {
    return injector().create<std::shared_ptr&lt;app>>();
}

// module2.hpp
#ifndef MODULE2_UNMB1JJ2
#define MODULE2_UNMB1JJ2

#include <boost/di.hpp>

namespace di = boost::di;

class app;

class module2 {
    using injector = di::injector<
        decltype(di::bind<app>::to(std::make_shared<app>()))
        //other bindings required
>;

public:
    injector configure() const;
};

// module2.cpp
#include "module2.hpp"
#include "module.hpp"
#include "app.hpp"
#include "things.hpp"
#include "that.hpp"

module2::injector module2::configure() const {
    return injector(
        di::bind<app>::to(module().create<std::shared_ptr&lt;app>>())
    );
}

// main.cpp
#include <boost/di.hpp>
#include "module2.hpp"

class app;

namespace di = boost::di;

int main() {
    auto injector = di::make_injector(module2());
    (void)injector.create<std::shared_ptr&lt;app>>();

    return 0;
}

///////////////////////////////////////-> ends here

Hope example will be helpful.

Thanks for your feedback, Kris

--
View this message in context: http://boost.2283326.n4.nabble.com/Is-there-any-interest-in-a-dependency-injection-library-tp4665526p4666012.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk