Add PluginProvider to allow for dependency injection of plugins

This is a preliminary attempt to fix #1389. Probably not mergeable yet, but I think this is on the right track.

I don't think this introduces any breaking changes. It would probably be a bit more elegant if we could change the API, but I tried to avoid it for now.