A design pattern made famous in the .NET community by Microsoft’s ASP.NET, the provider model explains is a pattern that supplies the end-developer with a plug-and-play architecture. The provider model is most often used when you have a consumer object that is dependent on specific functionality that can be supplied by one or more underlying systems. The major benefit of which is an increase in manageability and reusability.

It is important to note that we identify, generalize and abstract key functionality from each specific implementation to a specification (an interface in C#) to guarantee the plug-and-play architecture. Consider a site that has one or more backend storage devices for user credentials. We want to iterate through them when a user attempts to login but hardcoding them creates a strong dependency on their specific implementations. This can cause maintenance issues later on as one or more devices are added or removed. To keep the site agile, we can use the provider model to abstract the credential verification process. Consider the following provider specification.
public interface IAuthenticationProvider{
bool CheckCredentials(string username, string password);
}
We can then implement this in many different ways, utilizing an SQL database, an Active Directory server or even a simple text check.
public class SqlAuthenticationProvider : IAuthenticationProvider{
public bool CheckCredentials(string username, string password){
if(!IsValid(username, password)) return false;
// Run some SQL statement - set result to a bool
bool result = false;
return result;
}
}
public class TextAuthenticationProvider : IAuthenticationProvider{
public bool CheckCredentials(string username, string password){
return (username == "root" && password == "hello");
}
}
The beauty of this pattern is that as business requirements or APIs change, the core code of your application can remain unchanged. Instead you can update a configuration file, removing the need for recompilation and possibly a full test.
public class LoginPage : Page{
protected void Submit_Click(object sender, EventArgs e){
foreach(IAuthenticationProvider provider in Configuration.AuthenticationProviders){
if(provider.CheckCredentials(txtUsername.Text, txtPassword.Text)){
// set some session variables or a cookie
Response.Redirect("UserProfile.aspx");
}
}
}
}
I can hear you asking how this applies to game development and specifically the XNA universe. If you take a closer look at the XNA Framework you will find that this pattern is frequently used because of how flexible it is. For instance, any instance of DrawableGameComponent or GameComponent is a provider that implements some base interfaces. Similarly, any component you add to the services collection acts as a provider for anyone that consumes it.
namespace Microsoft.Xna.Framework{
public interface IGameComponent{
void Initialize();
}
public interface IDrawable{
event EventHandler DrawOrderChanged;
event EventHandler VisibleChanged;
void Draw(GameTime gameTime);
int DrawOrder { get; }
bool Visible { get; }
}
public interface IUpdateable{
event EventHandler EnabledChanged;
event EventHandler UpdateOrderChanged;
void Update(GameTime gameTime);
bool Enabled { get; }
int UpdateOrder { get; }
}
}
The above specifications are then implemented by child classes that you have probably run into and used before. Mainly GameComponent implements IUpdateable and IGameComponent while DrawableGameComponent inherits the former and implements the IDrawable interface. We can say here that the component classes provide functionality to the Game class through the IGameComponent, IUpdateable, and IDrawable interfaces.
namespace Microsoft.Xna.Framework{
public class GameComponent : IGameComponent, IUpdateable, IDisposable{
// ...
}
public class DrawableGameComponent : GameComponent, IDrawable{
// ...
}
}