Configurator Notes
ModuleManager integrates with Configurator in two ways;
First, ConfigurationSchema and TypeRegistry types are the basis for defining module resolvers. Modules
and Providers are available to be used as field types.
Second, and perhaps less obviously, ModuleManager itself is a ConfigurationSource. All fields that correspond
to module types receive synthetic assignments (low priority; above defaults, but below any user configuration)
that trigger the referenced module's generated type resolver.
These assignments are lazily evaluated, so if a dependency ends up being excluded because it is in an
unreferenced module, the module will not needlessly get instantiated. Furthermore, the child schemas created
for each module all have a condition set that tests whether an instance exists before their dependencies are
even evaluated.
Consider the case where the user can specify the concrete back-end implementation to use for a database interface; in one case, a simple local sqlite instance, in another, an expensive cloud service. Since lifecycle methods are called on all instantiated modules, it is highly desirable to not "wake up" a module unnecessarily.