I am building an application using Rust + Iced. I have various services for creating and manipulating my data. As of now I have one struct that contains all of the services and I pass it around as needed. But its growing more and more complicated and therefore, I was wondering if making this object static (or making the services singletons with something called Mutex) is bad design in Rust. What I would like to have is something like Spring Component, resp. ApplicationContext in java. I just "autowire" the service where it is needed, or I just use some global static that contains this services.
Just to give more context: now I have one service, that needs to observe changes in other services in order to recalculate, then for the calculation it actually needs to use 3 different services and it needs to be mutable. When I tried to implement Observer for this, I suddenly had to add a lot more places where I am handing over the Services object and it has to be mutable, because I need the one service mutable.
Here is a simplification of the services structure:
pub mod foo_service;
pub mod bar_service;
pub mod calculated_service;
pub mod etc_service;
...
// object implementing this trait needs to be available everywhere, passing it around means having this as argument almost everywhere
pub trait LibServices {
fn get_foo_service(&self) -> &FooService;
fn get_bar_service(&self) -> &BarService;
fn get_calculated_service(&self) -> &CalculatedService;
fn get_etc_service(&self) -> &EtcService;
}
static+Mutex, but I'm not sure that it is going to decrease the amount ofmut-tracking you'll end up doing.static+OnceLockto achieve something similar, e.g.rust fn get_my_dependency() -> &'static Foo { static ONCE: OnceLock<Foo> = OnceLock::new(); ONCE.get_or_init(|| Foo::new()) }