Provider Pattern 实现接口与具体实现的分离,通过配制文件灵活配制需要的具体实现。
沿用上次那个示例接口不变。
1.实现类必须继承System.Configuration.Provider.ProviderBase,这次我们多增加一个实现,看代码:
2.自定义配制节ActionProviderSection继承自ConfigurationSection,看代码:
3.ActionProviderCollection继承自ProviderCollection,注意引用namespace,System.Configuration.Provider
4.让写一个Service实现取对象,引用System.web,使用ProvidersHelper,代码如下:
5.让我们看一下配制文件是如何配制的:
6.最后的调用与测试:
ps:这是ProvidersHelper来自asp.net,也可以自己写,但其实没必要,引用就可以了,实际还可以用容器来实现,后期
将介绍容器实现。
沿用上次那个示例接口不变。
1.实现类必须继承System.Configuration.Provider.ProviderBase,这次我们多增加一个实现,看代码:
using System;
using SampleProviderPattern.Interface;
using System.Configuration.Provider;
namespace Machine
{
public class MachineT50 : ProviderBase,IAction
{
public void Burn()
{
Console.WriteLine("MachineT50 is burning now.");
}
}
public class MachineT800 : ProviderBase, IAction
{
public void Burn()
{
Console.WriteLine("MachineT800 is burning now.");
}
}
}
using SampleProviderPattern.Interface;
using System.Configuration.Provider;
namespace Machine
{
public class MachineT50 : ProviderBase,IAction
{
public void Burn()
{
Console.WriteLine("MachineT50 is burning now.");
}
}
public class MachineT800 : ProviderBase, IAction
{
public void Burn()
{
Console.WriteLine("MachineT800 is burning now.");
}
}
}
2.自定义配制节ActionProviderSection继承自ConfigurationSection,看代码:
using System.Configuration;
namespace Interface
{
public class ActionProviderSection : ConfigurationSection
{
/// <summary>
/// A collection of registered providers.
/// </summary>
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get { return (ProviderSettingsCollection)base["providers"]; }
}
/// <summary>
/// The name of the default provider
/// </summary>
[StringValidator(MinLength = 1)]
[ConfigurationProperty("defaultProvider", DefaultValue = "MachineT50Provider")]
public string DefaultProvider
{
get { return (string)base["defaultProvider"]; }
set { base["defaultProvider"] = value; }
}
}
}
namespace Interface
{
public class ActionProviderSection : ConfigurationSection
{
/// <summary>
/// A collection of registered providers.
/// </summary>
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get { return (ProviderSettingsCollection)base["providers"]; }
}
/// <summary>
/// The name of the default provider
/// </summary>
[StringValidator(MinLength = 1)]
[ConfigurationProperty("defaultProvider", DefaultValue = "MachineT50Provider")]
public string DefaultProvider
{
get { return (string)base["defaultProvider"]; }
set { base["defaultProvider"] = value; }
}
}
}
3.ActionProviderCollection继承自ProviderCollection,注意引用namespace,System.Configuration.Provider
using System;
using System.Configuration.Provider;
using SampleProviderPattern.Interface;
namespace Interface
{
public class ActionProviderCollection : ProviderCollection
{
/// <summary>
/// Gets a provider by its name.
/// </summary>
public new IAction this[string name]
{
get { return (IAction)base[name]; }
}
/// <summary>
/// Add a provider to the collection.
/// </summary>s
public override void Add(ProviderBase provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
if (!(provider is IAction))
throw new ArgumentException
("Invalid provider type", "provider");
base.Add(provider);
}
}
}
using System.Configuration.Provider;
using SampleProviderPattern.Interface;
namespace Interface
{
public class ActionProviderCollection : ProviderCollection
{
/// <summary>
/// Gets a provider by its name.
/// </summary>
public new IAction this[string name]
{
get { return (IAction)base[name]; }
}
/// <summary>
/// Add a provider to the collection.
/// </summary>s
public override void Add(ProviderBase provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
if (!(provider is IAction))
throw new ArgumentException
("Invalid provider type", "provider");
base.Add(provider);
}
}
}
4.让写一个Service实现取对象,引用System.web,使用ProvidersHelper,代码如下:
using System.Configuration;
using System.Configuration.Provider;
using System.Web.Configuration;
using SampleProviderPattern.Interface;
namespace Interface
{
/// <summary>
/// GeneralProviderService
/// </summary>
/// <remarks>author PetterLiu http://wintersun.cnblogs.com </remarks>
public class GeneralProviderService
{
private static IAction _generalprovider;
private static ActionProviderCollection _providers;
private static object _lock = new object();
public static IAction CreateActionProvider
{
get
{
LoadProvider();
return _generalprovider;
}
}
/// <summary>
/// Loads the provider.
/// </summary>
private static void LoadProvider()
{
if (_generalprovider == null)
{
lock (_lock)
{
if (_generalprovider == null)
{
ActionProviderSection section = (ActionProviderSection)ConfigurationManager.GetSection("ActionProvider");
if (section != null)
{
_providers = new ActionProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(IAction));
_generalprovider = _providers[section.DefaultProvider];
if (_generalprovider == null)
throw new ProviderException("Unable to load default Provider");
}
else
{
throw new ConfigurationErrorsException();
}
}
}
}
}
/// <summary>
/// GetProvider using name
/// </summary>
/// <param name="name">providername</param>
/// <returns>IAction</returns>
public static IAction GetProvider(string name)
{
LoadProvider();
return _generalprovider = _providers[name];
}
}
}
using System.Configuration.Provider;
using System.Web.Configuration;
using SampleProviderPattern.Interface;
namespace Interface
{
/// <summary>
/// GeneralProviderService
/// </summary>
/// <remarks>author PetterLiu http://wintersun.cnblogs.com </remarks>
public class GeneralProviderService
{
private static IAction _generalprovider;
private static ActionProviderCollection _providers;
private static object _lock = new object();
public static IAction CreateActionProvider
{
get
{
LoadProvider();
return _generalprovider;
}
}
/// <summary>
/// Loads the provider.
/// </summary>
private static void LoadProvider()
{
if (_generalprovider == null)
{
lock (_lock)
{
if (_generalprovider == null)
{
ActionProviderSection section = (ActionProviderSection)ConfigurationManager.GetSection("ActionProvider");
if (section != null)
{
_providers = new ActionProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(IAction));
_generalprovider = _providers[section.DefaultProvider];
if (_generalprovider == null)
throw new ProviderException("Unable to load default Provider");
}
else
{
throw new ConfigurationErrorsException();
}
}
}
}
}
/// <summary>
/// GetProvider using name
/// </summary>
/// <param name="name">providername</param>
/// <returns>IAction</returns>
public static IAction GetProvider(string name)
{
LoadProvider();
return _generalprovider = _providers[name];
}
}
}
5.让我们看一下配制文件是如何配制的:
<configuration>
<configSections>
<section name="ActionProvider" type="Interface.ActionProviderSection, Interface" requirePermission="false" allowDefinition="MachineToApplication" restartOnExternalChanges="true"/>
</configSections>
<ActionProvider defaultProvider="MachineT50Provider">
<providers>
<add name="MachineT50Provider" type="Machine.MachineT50, Machine"/>
<add name="MachineT800Provider" type="Machine.MachineT800, Machine"/>
</providers>
</ActionProvider>
</configuration>
<configSections>
<section name="ActionProvider" type="Interface.ActionProviderSection, Interface" requirePermission="false" allowDefinition="MachineToApplication" restartOnExternalChanges="true"/>
</configSections>
<ActionProvider defaultProvider="MachineT50Provider">
<providers>
<add name="MachineT50Provider" type="Machine.MachineT50, Machine"/>
<add name="MachineT800Provider" type="Machine.MachineT800, Machine"/>
</providers>
</ActionProvider>
</configuration>
6.最后的调用与测试:
Test
ps:这是ProvidersHelper来自asp.net,也可以自己写,但其实没必要,引用就可以了,实际还可以用容器来实现,后期
将介绍容器实现。