Hi everyone! I'm hoping someone will be able to help me out here.
In the internals of coi, I unfortunately have to rely heavily on a double
Arc. Here's some details about the internals of
It's a dependency injection crate, so users will register a mapping of keys to providers, and will later try to resolve some type
T with a previously registered key. The former is done through the container registration (example here) and the latter through resolving, e.g.
Provide type is responsible for providing the specific type
T once requested. This is setup with an associated type on the
Output. So when the providers are registered, they're stored as
Arc<dyn Provide<Output = T>...> to hide the actual provide impl. Then those are stored in
Arc<dyn Any...> so that the kind of
Provide can also be erased so they're all the same size (the
Output=T is what made it complicated for me) and can be stored in a container (the type that's converted to
Arc<dyn Any> is an
The container takes ownership over the providers for now, but I'm open to alternatives. The container does usually need to be moved though, sometimes to another thread (see here in coi-actix-sample), so it's not always possible to just use a shared reference.
When the objects are requested through the
resolve call, we first lookup the key to ensure we're actually storing a provider for that value (there's also other work that happens first to check for existing resolutions, but that's separate from this request for help, I think). That stored value is still just
Arc<dyn Any...> so we get a reference to the inner
dyn Any and attempt to call
downcast_ref::<Arc<dyn Provide<Output = T>...>>() on it.
I really dislike the multiple usages of
Arc here. Is there any obvious way to improve this that I'm missing, or will this require a lot more in depth analysis to fix?
This is where registration occurs: https://github.com/Nashenas88/coi/blob/master/src/lib.rs#L813
And this is where the downcasting and providing occurs: https://github.com/Nashenas88/coi/blob/master/src/lib.rs#L616-L623