1

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;
}
5
  • It is generally considered good practice to avoid global values, because they make code harder to test. Now, if you absolutely need to have global values, you can indeed have static + Mutex, but I'm not sure that it is going to decrease the amount of mut-tracking you'll end up doing. Commented Nov 7, 2023 at 9:37
  • Thanks. And I assume there is no such thing as dependency injection in Rust, right? Commented Nov 7, 2023 at 10:45
  • Not really, but you can use static + OnceLock to achieve something similar, e.g. rust fn get_my_dependency() -> &'static Foo { static ONCE: OnceLock<Foo> = OnceLock::new(); ONCE.get_or_init(|| Foo::new()) } Commented Nov 7, 2023 at 10:56
  • Thank you for the tip, I will read about this a bit. :) Commented Nov 7, 2023 at 11:02
  • I think AOP also can help in this kind of situations. Commented Mar 3, 2024 at 18:34

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.