Boost logo

Boost :

Subject: Re: [boost] Is there any interest in a dependency injection library?
From: Sohail Somani (sohail_at_[hidden])
Date: 2014-07-29 20:41:16


On 2014-07-29, 1:04 PM, Kris wrote:
>> Somehow, Guice survives by detecting things
>> at runtime so I would take from their experience that it is not a
>> completely terrible proposition.
>
> Yea, but they didn't really have the opportunity to do it as well, did they?
> In the end C++ compile time checking possibilities are more complex than
> Java ones.
> I'm not saying runtime checking it's terrible proposition, but IMHO
> compile time checking will always be a better option, just because
> errors might be spotted earlier.
>
>> Is it possible to automatically convert
>> a static injector to a dynamic one? This might be the best of both
>> worlds. That is, something like this:
>>
>> di::injector<>
>> SomeModule() {
>> return di::make_injector(
>> di::bind<ilogger,logger>(),
>> di::bind<ilogic,logic>()
>> );
>> }
>>
>> I think you have all the information you need to do this. I'd encourage
>> you to continue to develop the "dynamic" portion in a way that you're
>> happy with it. Personally, I'd be happy if the above worked.
>
> Yea, its possible to convert static injector to dynamic one.
> Presented proof-of-concept
> (https://github.com/krzysztof-jusiak/di_runtime_injector)
> was able to do so. There was one thing which couldn't be implemented
> in runtime tho - which was interface deduction.
>
> di::injector<> injector = di::make_injector(
> di::deduce<implementation>()
> // didn't work properly in runtime, use di::bind<interface,
> implementation>() instead
> );
>
> But it's not as big deal I guess, although make both interfaces a bit
> different :/
> Anyway I can implement runtime injector fairly easy.
> I'm just still not totally convinced it's really worth to do so, but
> definitely runtime injector might be an option to choose from in the end?

I'm ONLY interested in it for one reason: separately compiling bindings.
I don't care about anything else. You are 100% correct that I prefer
compile-time to run-time. One observation: each application will usually
have a root "app" type, but separate modules will not. So it doesn't
make sense to return an injector with a root type there.

I promise you that I will try and use your library soon when I find a
round tuit and perhaps at that point, I will find your solution is
sufficient, but in the meantime I can only suggest things based on my
personal experience.

So, the kind of code I'd like to write. This is probably nonsense for
your library, but I'm hoping it makes some sort of sense:

// ModuleA.cpp
#include "boost/di/whatever.hpp"

class this; class that; class animal; class frog; // ??

????
ConfigureModuleA() {
   return make_injector(
     bind<this,that>(),
     bind<animal,frog>()
   );
}

// app.hpp
class app {
   explicit
   app(this*t); // requires this (bound to that)
};

// ModuleB.cpp
#include "boost/di/whatever.hpp"
// I think you need to have these, but I'm not sure if you can do it
without it
#include "this.hpp"
#include "app.hpp"

????
ConfigureModuleB() {
   return make_injector(
      deduce<app>() // not sure if I'm using deduce correctly
   );
}

// main.cpp
#include "boost/di/whatever.hpp"

int main() {
   injector inj{ConfigureModuleA,ConfigureModuleB};
   inj.construct<app>().run();
}

Is something like this already possible? The syntax is not important,
but how would you separately compile these two modules?

Thanks!

Sohail


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