Provider Pattern 实现接口与具体实现的分离,通过配制文件灵活配制需要的具体实现。
沿用上次那个示例接口不变。

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.");
        }
    }
}

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; }
        }
    }
}

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);
        }
    }
}

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];      
        }

    }
}

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>

6.最后的调用与测试:
Test

ps:这是ProvidersHelper来自asp.net,也可以自己写,但其实没必要,引用就可以了,实际还可以用容器来实现,后期
将介绍容器实现。
 
posted on 2008-10-25 18:06  PetterLiu  阅读(2646)  评论(0编辑  收藏  举报