Boost logo

Boost :

Subject: Re: [boost] Is there any interest in a dependency injection library?
From: Kris (krzysztof_at_[hidden])
Date: 2014-07-27 17:46:48


Hi Sohail,

> So that example is fine when it comes to a single type, but I have
> hundreds of types that are separately compiled. Creating an injector for
> each type is cumbersome. Is there a way you can come up with a solution
> that is generic? I know you suggested type lists but that is too much of
> a burden.

Okay, the example was limited to one type, but to the - only - type which
should be created if composition root (the only call of
create/construct/getInstance/...) would have been applied. Otherwise,
agreed, example was limited to one type and type list could have been a bit
hard to use after all as well.

Nevertheless I see few solutions to types which are separately compiled:
1) if composition root is applied, it shouldn't be a problem with the
solution shown in the thread already
2) usage of forward declarations seems to be working fine with modules -
example with separately compiled modules and forward decelerated types in
header files might be found in:
http://krzysztof-jusiak.github.io/di/boost/libs/di/doc/html/di/examples/more_examples.html#di.examples.more_examples.modules_hpp_cpp

So, in the example, the basic idea is to forward declaration needed types in
configuration header file and use them in cpp file.

#module.hpp
class implementation;

class module {
    using injector = di::injector<di::deduce&lt;implementation>>;
public:
    injector configure() const;
};

#module.cpp
#include "module.hpp"
#include "implementation.hpp"

module::injector module::configure() const {
    return di::injector<di::deduce&lt;implementation>>();
}

3) mixed runtime/compile time solution, which, at some point, I made
proof-of-concept of, but I did give up on in the end, due to the fact I
wasn't able to get compile time checking working in many cases, runtime
overhead and implementation complexity didn't help either - anyway such
solution might be easily implemented on top of current library,
proof-of-concept and the idea might be found in:
https://github.com/krzysztof-jusiak/di_runtime_injector

di::injector<> injector;
injector.install(
    di::bind<interface, implementation>()
);
injector.install(
    di::bind<int>::to(42)
);
injector.create<app>();

> In my library, there was only one case I cared about that may not be
> caught at compile-time: the (lack of) concrete implementation in a base
> class. I haven't bothered to fix it because the error happens
> immediately at runtime and the exception thrown tells you what to do.

Yea, but IMHO it depends on the project scale and tests coverage tho, a lot
of projects are so huge and so badly tested that runtime exception may
happen in production either way. Besides that compile time checking give so
much opportunities like limiting allowed types, checking for circular
dependencies, etc...

> Other than that, I don't recall a single run-time issue beyond this
> (threading issues aside), but what I was referring to regarding your
> compile-time bit was that the way you've written it, you can demand an
> implementation for a base class, which is pretty cool to me. If there
> was some way to marry your static checking with the convenience of
> separately compiling the bindings without having to do it for each
> individual type, I'd switch to your library in a heartbeat!

Thanks:) Anyway IMHO runtime binding may have some abilities of static
checking, but exceptions will have to be thrown there either way. Separately
compiling bindings definitely might be achieved with static checking for
example with usage of forward declarations or composition root approach.

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-tp4665526p4665601.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