Provider Pattern 实现接口与具体实现的分离,通过配制文件灵活配制需要的具体实现。
沿用上次那个示例接口不变。
1.实现类必须继承System.Configuration.Provider.ProviderBase,这次我们多增加一个实现,看代码:
2.自定义配制节ActionProviderSection继承自ConfigurationSection,看代码:
3.ActionProviderCollection继承自ProviderCollection,注意引用namespace,System.Configuration.Provider
4.让写一个Service实现取对象,引用System.web,使用ProvidersHelper,代码如下:
5.让我们看一下配制文件是如何配制的:
6.最后的调用与测试:
Test
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.最后的调用与测试:

ps:这是ProvidersHelper来自asp.net,也可以自己写,但其实没必要,引用就可以了,实际还可以用容器来实现,后期
将介绍容器实现。
分类:
ASP.NET 2.0
, DesignPatterns
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库