Actually your question is good. To make it very simple, we define services in Angular JS to achieve our features. Provider is one of the way to configure how that services should work. There are some more concepts namely Values, Constants, Factory, Service and Decorator in Angular JS, which can help us intercept the services in different manners. Please check the below link.
https://docs.angularjs.org/guide/providers
Coming back to the Providers, they are used to define application wide configurations that needs to be done even before application starts. Since config blocks are executed before the Angular JS modules are loaded we configure providers under them. Since the modules would not have been loaded by that time you can't access services inside a config block.
Run blocks are executed once all the modules are loaded by the $injector. Once you enter a run block, you are not allowed to configure your provider any more since your services will be loaded anyway. That's the reason you can't access providers inside a run block.
Let's see an example. I have designed my application to support both user and admin screens. But the features related to them are defined in their respective services. I want to load only the appropriate services when a user logs in. We achieve that using a provider as below.
Defining rolesProvider
myApp.provider("roles", function rolesProvider(){
var role;
this.setRole = function(value) {
role = value;
}
this.$get = function rolesFactory() {
if(role === "user") {
return new userRole();
} else {
return new adminRole();
}
}
});
Configuring rolesProvider as a user
myApp.config(["rolesProvider"], function(rulesProvider){
rulesProvider.setRole("user");
});
My application will be configured to run as a user rather than as an admin when the application kicks off.
Let me know if you need more explanations.