Register functions which create each type of provider rather than the provider types themselves so that the concrete types don't need to be publicly exposed, and use a static list of providers rather than registering them at runtime.