In the Yet Another Whidbey Post vein, I just wanted to talk a bit deeper on the provider model than what you can currently find on google or msdn.
Usually, when most people hear about it and how it’s used, the first thing they usually think is… “that’s going to be useful for a lot of people in a lot of ways”. It’s great for the app dev who just wants simple functionality like login and membership and personalization. It’s also great for the guys who want to tweak the hell out of how those kinds of things are implemented. And at a different level, it’s great for third parties to provide presentation and business layer tiers for redistributed apps, while allows their clients to provide the final hook up to backend.
But then the second reaction kinda depends on whether that person has learned about patterns. If they have, then they’ll probably connect the provider model to a couple of the GOF patterns and think, “oh great, this provider stuff is just a buzzword on top of a well known pattern.” Well, to that, I say that the provider model is a bit more than just a general pattern. The model is a composition/blending of the Abstract Factory, Strategy, Singleton and Component Configurator patterns, as well as, and this is important, an implementation spec for how and where those patterns connect, as well as how to implement some of the more hand-wavy parts of the pattern descriptions.
To start from the API user point of view... It kind of has that Singleton feel. It’s not quite a strict implementation of Singleton, but it’s the best fit as far I know. The idea of having a static class that exposes the API, while lazy loading and proxying requests to an instance-based implementor… It’s not a pattern that has a name as of yet (that I know of, please correct me if I’m wrong ).
The interaction and point behind the various implementers, is kind of a blending between Abstract Factory and Strategy. It’s a Strategy in that you have individual strategies for implementing a feature set. The strategy implementers don’t derive from the type the client uses, but instead the client calls a public “face” class’s methods, and the face class knows about and calls the methods on a abstract implementation base class. With providers, the face class generally has the same methods (albeit static) as the implementations, but that is by no means a requirement.
However, it kind of breaks with Strategy in that the pattern kind of suggests that the client actively chooses the strategy to use, maybe even on a call by call basis, based on current conditions. In this respect, it’s more like Abstract Factory, in that the implementation is a configuration option, chosen via Component Configurator, as a separate config file. This is of course the right thing. The controls shouldn’t be deciding the provider, the app developer should be doing that. It’s not fully Abstract Factory, tho, because abstract factory is about creating other types. Provider implementions are about doing tasks not creating custom typed objects.
And then the spec comes in. The spec is mostly about making both configuration for the app dev, and implementation of custom provider implementations, as easy and predictable as possible.
In configuration, the spec defines how the xml configuration section should look. So that an app dev that knows how one provider feature works, such as Personalization, would know, in a general sense, how others such as Membership should work. Or that a tool can be written that can share significant portions of code for configuring the various features.
For the individual provider implementer, the idea is that as much of the hard work as possible went into the feature provider face. Things like consuming the config files, determining provider, and getting the API right, is done by the feature’s face. And that the abstract base class which defines how provider implementers work is as simple and clear as possible to derive from and implement. The spec defines the good practice base classes that hint at how the configuration, initialization and usage will work. It also defines common naming schemes so that providers APIs are easy to discover and use.
So anyway, that’s how I see it all coming together. And while it’s obviously not some big revolution that solves world hunger and pioneers peace in war torn areas of the world… Clearly, it is a nice and ultimately useful evolutionary step.
In closing, I think this stuff is quite exciting. And not just because I’ll be able to do things faster and easier when Whidbey comes out, but because it gives us all a great model to use in our current apps when we have similar infrastructure problems to solve. So ultimately, this article wasn’t so much about Whidbey as I may have let on in the beginning, but more about how we can use these insights to make our current apps better both today and tomorrow.