There's a scenario I have where, in the main entry point of my C# program, I iterate a directory of managed DLLs, load each of them, and pass a factory object to each of them to get a mapping of implementations for various public interfaces. After the iteration is completed, I have one big map of interfaces and their corresponding implementations.
This factory object is needed by many unrelated objects in the system. There's also state that goes with the factory that identifies if specific DLLs were found, because knowing if I have a certain implementation sometimes influences the UI (disabling elements in the UI when they are not present).
What is the best way to share this factory + the accompanying informational state? I can either store it as a global, or I can pass it through hundreds of functions in my code, but I like neither of these solutions.
Challenges like this make it really hard to avoid the Singleton pattern. I can't be creating these factories on-demand all over the place because I would be repeating the same, heavy work each time and that's unnecessary.
What are some alternative solutions that don't involve abusing global variables (which is error prone), polluting interfaces, or impacting performance? Note that if the singleton pattern (as a class) is justified here and there are no reasonable alternatives, I can accept that as an answer.
As far as research goes, I did find answers like this one that mention dependency injection, however I'm not sure how that would apply here. I've also considered some sort of observer pattern for this, but again I don't see how I could use that mechanism to avoid the problems here. It feels like no matter what, when you boil each idea down to the essentials, it comes down to either global state or polluting interfaces.