-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Is your feature request related to a problem? Please describe.
Structuring programs made with kangaru can be challenging. Programs usually don't want to depend on initialization order, and don't want to care if an abstract class has yet been constructed or not. This has been a recurring challenge and feature request from many different users.
Describe the solution you'd like
A modular architecture that lets you create services using function, and consume services made from other modules. Something like this:
struct service_a {};
struct service_b { service_a& a; };
struct service_c { service_b& b; };
struct service_d { service_a& a; service_c c; };
struct module_1 {
auto provide() -> kangaru::frob_sources<service_a&, service_b&> {
return kangaru::something{
[]{ return service_a{}; },
[](service_a& a) { return service_b{.a = a}; }
};
}
};
struct module_2 {
module_1 m1;
auto provide() -> kangaru::frob_sources<service_c, service_d&> {
return kangaru::something{
m1,
[](service_b& b){ return service_c{.b = b}; },
[](service_a& a, service_c c) { return service_d{.a = a, .c = c}; }
};
}
};
As you can see in this example, service creation is grouped by modules. Each module makes their own service available through the provide
function. Other modules can only use services from their explicit dependencies.
Technically, this would allow types in the signature to be abstract classes, and the functions to create an instance of a concrete type.
We're already quite close to this architecture if one uses kangaru::with_function_call
, but I would like a more beautiful syntax and an easy way to structure the sources in modules.
Describe alternatives you've considered
An alternative would be to simply support dynamically insert functions in the dynamic container. This would imply keeping exceptions, but with the advantage of keeping current infrastructure.
I personally don't like this alternative since it's less powerful, still dependent on executing something to make the container functional.