Hello, I am writing a dependency injection based workflow for a project. I have a
HashMap<TypeId, Arc<RwLock<dyn Any>>>
where injectable resources are stored. I'm basing my API off a similar style like that used in Bevy, something like
fn my_step(res1: &ResourceType1, res2: &mut ResourceType2) { ... }
It needs to support variadic argument lengths with any combo of & and &mut so instead of implementing for every combination I'm dealing with an abstraction for each parameter. The abstractions are responsible for retrieving the value from the map so it can be passed to the function, this is where my issue lies.
I'm effectively following this resource https://promethia-27.github.io/dependency_injection_like_bevy_from_scratch/introductions.html however I have one major change for my purposes, my system needs to work across threads for parallelization. So instead of a Box<dyn Any> I'm dealing with an Arc<RwLock<dyn Any>> which works up until this point without issue. However because the abstraction for a given parameter is responsible for knowing how to get the value, the abstraction needs to be the one to obtain the read or write lock (since outside the abstraction it doesn't know if it needs mutability or not). But the value is only valid as long as the lock is kept alive, and the value is needed outside the abstraction. In essence like the following:
let value1 = param1.get_value(&map); // RwLockReadGuard is obtained within get_value
let value2 = param2.get_value(&map); // RwLockWriteGuard is obtained within get_value
(self.func)(value1, value2); // Call the method with dependencies injected
// I need some way to defer the releasing of the guards to here
I've tried a variety of approaches so far, the one I felt had the most promise would be to have the value be returned wrapped in a struct that also takes over ownership of the guard, such that when it goes out of scope after the call to func() the lock would be released instead of within the get_value(). I don't know to get such a concept working and whether of not that's even the best approach.