The static class is the last part to creating a provider.
It is a key component in exposing your provider to the consumers. This class
pulls together all the parts, by using the configuration section to determine
which provider is the default provider, creating the list of providers, and
executing the methods that are called in the default provider. The static class
is declared with the static keyword, as all methods should be static in this
way. The static method exposes the provider as such:
Listing 8
public static bool NewsletterExists(string newsletterName)
{
return Newsletter.DefaultProvider.NewsletterExists(newsletterName);
}
In addition, if you desire to have overloaded methods, to
provide only some of the parameters needed, you can do so in the static class,
such as the AddNewsletter method:
Listing 9
public static void AddNewsletter(string newsletterName)
{
Newsletter.AddNewsletter(newsletterName, null);
}
public static void AddNewsletter(string newsletterName, string description)
{
Newsletter.DefaultProvider.AddNewsletter(newsletterName, description);
}
How does the provider get initialized, as well as determining
the default provider? This occurs in the Initialize and InitializeProviders
methods. But before we look at them, we need to understand their importance.
In essence, the providers and default provider are lazy loaded, meaning they
are loaded whenever they are accessed. The following is the definition for the
DefaultProvider and Providers properties. Note that the Initialize method is
called.
Listing 10
public static NewsletterProvider DefaultProvider
{
get
{
Newsletter.Initialize();
return Newsletter._defaultProvider;
}
}
public static NewsletterProviderCollection Providers
{
get
{
Newsletter.Initialize();
return Newsletter._providers;
}
}
In the initialize method, a boolean value tracks whether
this method has been called previously. If not, then a lock is performed in
this method, to ensure that no other instance has done anything with these
providers. This is the reason for the second check; to ensure that the default
provider is really null, even after the lock is placed.
Listing 11
private static void Initialize()
{
if (!_initialized)
{
if (_defaultProvider == null)
{
lock(_lock)
{
//Do this again to make sure provider is still null,
//according to MSDN
if (_defaultProvider == null)
Newsletter.InitializeProviders();
}
}
//Set the initialized to true, so this doesn't occur again
_initialized = true;
}
}
In the Initialize method, the call was made to initialize
the providers in the providers collection. The ProviderSettingsCollection needs
converted into a collection of the actual provider class type
(NewsletterProvider derived classes). In the code below, I have a helper
method of my own to assist with this conversion. The actual conversion takes
place in a single line, using ProvidersHelper.InstantiateProviders(section.Providers,
providers, typeof(NewsletterProvider)) method call. ProvidersHelper is already
defined in the framework, whereas ProviderHelper is defined in my application.
Listing 12
private static void InitializeProviders()
{
NewsletterSection section = NewsletterSection.Instance;
_providers = ProviderHelper.InitializeProviders<NewsletterProviderCollection,
NewsletterProvider>(section);
_defaultProvider = _providers[section.DefaultProvider];
if (_defaultProvider == null)
throw new ProviderException("The provider couldn't be instantiated");
}
Now we can use our static class to do whatever we need to
with this framework. It can be utilized in a web or windows application, as
long as all the appropriate references are met.