
That's not exactly what I meant.
What I meant is that if library A uses DI mechanism A, can I describe to a Boost.DependencyInjection that mechanism A, such that mechanism A maps 100% into Boost.DependencyInjection.
To put it back into terms of Allocators, how do I tell a Boost.DependencyInjection that for all std::vector<T, X> where X meets the Allocator Concept, std::vector<T, X> can have an instance X injected into its construction such that one can now write:
const auto injector = di::make_injector( di::bind<std::vector>.to<MyAllocator>() ); injector.create<std::vector<int>>()
... and that makes me a std::vector<int, MyAllocator<int>>.
I'm sure it's probably possible, it's just I from my best reading of the docs, I think it's quite awkward to do right now. And I think it ought to not be awkward in anything Boost approves.
With DI that can be already achieved with constructor/named template deduction. Let's try it then, shall we? For example, we have a custom allocator my_allocator template<class T> struct my_allocator : std::allocator<T> {}; And 2 dependencies dep1, dep2 were we want a custom allocator to be injected (for vector and set) template<class TAllocator = class Allocator> struct dep1 { explicit(true) dep1(std::vector<int, TAllocator>) {} }; template<class TAllocator = class Allocator> struct dep2 { dep2(const std::set<int, std::less<int>, TAllocator>&, std::unique_ptr<interface> i) { assert(dynamic_cast<implementation*>(i.get())); } }; and the application app1, app2 (notice different constructor parameters) template<class TAllocator = class Allocator> struct app1 { app1(dep1<TAllocator>, dep2<TAllocator>) {} }; template<class TAllocator = class Allocator> struct app2 { app2(std::shared_ptr<dep2<TAllocator>>, const dep1<TAllocator>&) {} }; Let's make the injector and override Allocator with my_allocator auto injector = di::make_injector( di::bind<class Allocator>.to<my_allocator<int>>() // won't compile if missing (that's what means compile-time DI, it won't be an exception it will be a compilation error , di::bind<interface>.to<implementation>() // won't compile if missing ); int main() { auto app1 = injector.create<app1>(); // Okay will create app1 with my_allocator injected into all dependencies which are using class Allocator auto app2 = injector.create<app2>(); // Okay will create app2, just a show-case that the order and types of constructor parameters doesn't matter for DI } Full example -> https://godbolt.org/z/sPszoG Right, now for 2e2 testing we would like to change the allocator for test_allocator but keep all other dependencies auto test_injector = di::make_injector( std::move(injector), // old injector di::bind<class Allocator>.to<test_allocator>() [di::override] ); int main() { auto app1 = test_injector.create<app1>(); // Okay will create app1 with test_allocator injected into all dependencies which are using class Allocator }