原文:乐在其中设计模式(C#) - 提供者模式(Provider Pattern)

[索引页][源码下载]

乐在其中设计模式(C#) - 提供者模式(Provider Pattern)

作者:webabcd





介绍

为一个API进行定义和实现的分离。





示例

有一个Message实体类,对它的操作有Insert()和Get()方法,持久化数据在SqlServer数据库中或Xml文件里。根据配置文件中的配置来决定数据持久化方案是使用SqlServer数据库还是Xml文件。





MessageModel

using System;



namespace Pattern.Provider

{

    /**//// <summary>

    /// Message实体类

    /// </summary>

    public class MessageModel

    {

        /**//// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="msg">Message内容</param>

        /// <param name="pt">Message发布时间</param>

        public MessageModel(string msg, DateTime pt)

        {

            this._message = msg;

            this._publishTime = pt;

        }



        private string _message;

        /**//// <summary>

        /// Message内容

        /// </summary>

        public string Message

        {

            get { return _message; }

            set { _message = value; }

        }



        private DateTime _publishTime;

        /**//// <summary>

        /// Message发布时间

        /// </summary>

        public DateTime PublishTime

        {

            get { return _publishTime; }

            set { _publishTime = value; }

        }

    }

}

MessageProvider

using System.Configuration.Provider;

using System.Collections.Generic;



namespace Pattern.Provider

{

    /**//// <summary>

    /// 操作Message抽象类

    /// </summary>

    public abstract class MessageProvider : ProviderBase

    {

        /**//// <summary>

        /// 插入Message

        /// </summary>

        /// <param name="mm">Message实体对象</param>

        /// <returns></returns>

        public abstract bool Insert(MessageModel mm);



        /**//// <summary>

        /// 获得Message

        /// </summary>

        /// <returns></returns>

        public abstract List<MessageModel> Get();

    }

}

SqlMessageProvider

using System;

using System.Collections.Specialized;

using System.Collections.Generic;



using System.Configuration.Provider;

using System.Configuration;



namespace Pattern.Provider

{

    /**//// <summary>

    /// Sql方式操作Message

    /// </summary>

    public class SqlMessageProvider : MessageProvider

    {

        private string _connectionString;



        /**//// <summary>

        /// 插入Message

        /// </summary>

        /// <param name="mm">Message实体对象</param>

        /// <returns></returns>

        public override bool Insert(MessageModel mm)

        {

            // 代码略

            return true;

        }



        /**//// <summary>

        /// 获取Message

        /// </summary>

        /// <returns></returns>

        public override List<MessageModel> Get()

        {

            List<MessageModel> l = new List<MessageModel>();

            l.Add(new MessageModel("SQL方式,连接字符串是" + this._connectionString, DateTime.Now));



            return l;

        }



        /**//// <summary>

        /// 初始化提供程序。

        /// </summary>

        /// <param name="name">该提供程序的友好名称。</param>

        /// <param name="config">名称/值对的集合,表示在配置中为该提供程序指定的、提供程序特定的属性。</param>

        public override void Initialize(string name, NameValueCollection config)

        {

            if (string.IsNullOrEmpty(name))

                name = "MessageProvider";



            if (null == config)

                throw new ArgumentException("config参数不能为null");



            if (string.IsNullOrEmpty(config["description"]))

            {

                config.Remove("description");

                config.Add("description", "SqlServer操作Message");

            }



            base.Initialize(name, config);



            string temp = config["connectionStringName"];

            )

                throw new ProviderException("connectionStringName属性缺少或为空");



            _connectionString = ConfigurationManager.ConnectionStrings[temp].ConnectionString;

            )

            {

                throw new ProviderException("没找到'" + temp + "'所指的连接字符串,或所指连接字符串为空");

            }



            config.Remove("connectionStringName");

        }

    }

}

XmlMessageProvider

using System;

using System.Collections.Specialized;

using System.Collections.Generic;



using System.Configuration.Provider;

using System.Configuration;



namespace Pattern.Provider

{

    /**//// <summary>

    /// Xmll方式操作Message

    /// </summary>

    public class XmlMessageProvider : MessageProvider

    {

        private string _connectionString;



        /**//// <summary>

        /// 插入Message

        /// </summary>

        /// <param name="mm">Message实体对象</param>

        /// <returns></returns>

        public override bool Insert(MessageModel mm)

        {

            // 代码略

            return true;

        }



        /**//// <summary>

        /// 获取Message

        /// </summary>

        /// <returns></returns>

        public override List<MessageModel> Get()

        {

            List<MessageModel> l = new List<MessageModel>();

            l.Add(new MessageModel("XML方式,连接字符串是" + this._connectionString, DateTime.Now));



            return l;

        }



        /**//// <summary>

        /// 初始化提供程序。

        /// </summary>

        /// <param name="name">该提供程序的友好名称。</param>

        /// <param name="config">名称/值对的集合,表示在配置中为该提供程序指定的、提供程序特定的属性。</param>

        public override void Initialize(string name, NameValueCollection config)

        {

            if (string.IsNullOrEmpty(name))

                name = "MessageProvider";



            if (null == config)

                throw new ArgumentException("config参数不能为null");



            if (string.IsNullOrEmpty(config["description"]))

            {

                config.Remove("description");

                config.Add("description", "XML操作Message");

            }



            base.Initialize(name, config);



            string temp = config["connectionStringName"];

            )

                throw new ProviderException("connectionStringName属性缺少或为空");



            _connectionString = ConfigurationManager.ConnectionStrings[temp].ConnectionString;

            )

            {

                throw new ProviderException("没找到'" + temp + "'所指的连接字符串,或所指连接字符串为空");

            }



            config.Remove("connectionStringName");

        }

    }

}

MessageProviderCollection

using System.Configuration.Provider;

using System;



namespace Pattern.Provider

{

    /**//// <summary>

    /// Message的Provider集合类

    /// </summary>

    public class MessageProviderCollection : ProviderCollection

    {

        /**//// <summary>

        /// 向集合中添加提供程序。

        /// </summary>

        /// <param name="provider">要添加的提供程序。</param>

        public override void Add(ProviderBase provider)

        {

            if (provider == null)

                throw new ArgumentNullException("provider参数不能为null");



            if (!(provider is MessageProvider))

                throw new ArgumentException("provider参数类型必须是MessageProvider.");



            base.Add(provider);

        }

    }

}

MessageProviderConfigurationSection

using System.Configuration;



namespace Pattern.Provider

{

    /**//// <summary>

    /// Message的Provider的配置

    /// </summary>

    public class MessageProviderConfigurationSection : ConfigurationSection

    {

        private readonly ConfigurationProperty _defaultProvider;

        private readonly ConfigurationProperty _providers;

        private ConfigurationPropertyCollection _properties;

        

        /**//// <summary>

        /// 构造函数

        /// </summary>

        public MessageProviderConfigurationSection()

        {

            _defaultProvider = new ConfigurationProperty("defaultProvider", typeof(string), null);

            _providers = new ConfigurationProperty("providers", typeof(ProviderSettingsCollection), null);

            _properties = new ConfigurationPropertyCollection();



            _properties.Add(_providers);

            _properties.Add(_defaultProvider);

        }



        /**//// <summary>

        /// Message的默认的Provider

        /// </summary>

        [ConfigurationProperty("defaultProvider")]

        public string DefaultProvider

        {

            get { return (string)base[_defaultProvider]; }

            set { base[_defaultProvider] = value; }

        }



        /**//// <summary>

        /// Message的所有的Provider集合

        /// </summary>

        [ConfigurationProperty("providers", DefaultValue = "SqlMessageProvider")]

        [StringValidator(MinLength )]

        public ProviderSettingsCollection Providers

        {

            get { return (ProviderSettingsCollection)base[_providers]; }

        }



        /**//// <summary>

        /// Message的Provider的属性集合

        /// </summary>

        protected override ConfigurationPropertyCollection Properties

        {

            get { return _properties; }

        }

    }

}

Message

using System;

using System.Collections.Generic;

using System.Configuration;

using System.Web.Configuration;



namespace Pattern.Provider

{

    /**//// <summary>

    /// 暴露给客户端用的Message的类(Context)

    /// </summary>

    public class Message

    {

        private static bool m_isInitialized = false;

        private static MessageProviderCollection _providers = null;

        private static MessageProvider _provider = null;



        /**//// <summary>

        /// 静态构造函数,初始化

        /// </summary>

        static Message()

        {

            Initialize();

        }



        /**//// <summary>

        /// 插入信息

        /// </summary>

        /// <param name="mm">Message实体对象</param>

        /// <returns></returns>

        public static bool Insert(MessageModel mm)

        {

            return _provider.Insert(mm);

        }



        /**//// <summary>

        /// 获取信息

        /// </summary>

        /// <returns></returns>

        public static List<MessageModel> Get()

        {

            return _provider.Get();

        }



        private static void Initialize()

        {

            try

            {

                MessageProviderConfigurationSection messageConfig = null;



                if (!m_isInitialized)

                {



                    // 找到配置文件中“MessageProvider”节点

                    messageConfig = (MessageProviderConfigurationSection)ConfigurationManager.GetSection("MessageProvider");



                    if (messageConfig == null)

                        throw new ConfigurationErrorsException("在配置文件中没找到“MessageProvider”节点");



                    _providers = new MessageProviderCollection();



                    // 使用System.Web.Configuration.ProvidersHelper类调用每个Provider的Initialize()方法

                    ProvidersHelper.InstantiateProviders(messageConfig.Providers, _providers, typeof(MessageProvider));



                    // 所用的Provider为配置中默认的Provider

                    _provider = _providers[messageConfig.DefaultProvider] as MessageProvider;



                    m_isInitialized = true;



                }

            }

            catch (Exception ex)

            {

                string msg = ex.Message;

                throw new Exception(msg);

            }

        }



        private static MessageProvider Provider

        {

            get

            {

                return _provider;

            }

        }



        private static MessageProviderCollection Providers

        {

            get

            {

                return _providers;

            }

        }

    }

}

Web.config

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <configSections>

    <section name="MessageProvider" type="Pattern.Provider.MessageProviderConfigurationSection, Pattern.Provider" />

  </configSections>

  <MessageProvider defaultProvider="SqlMessageProvider">

    <providers>

      <add name="XmlMessageProvider" type="Pattern.Provider.XmlMessageProvider, Pattern.Provider" connectionStringName="XmlConnection" />

      <add name="SqlMessageProvider" type="Pattern.Provider.SqlMessageProvider, Pattern.Provider" connectionStringName="SqlConnection" />

    </providers>

  </MessageProvider>

  <connectionStrings>

    <add name="SqlConnection" connectionString="server=.;database=db;uid=sa;pwd=sa" />

    <add name="XmlConnection" connectionString="XmlPath" />

  </connectionStrings>

</configuration>

Test

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;



using Pattern.Provider;



public partial class Provider : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        Response.Write(Message.Insert(new MessageModel("插入", DateTime.Now)));

        Response.Write("<br />");

        Response.Write(Message.Get()[].PublishTime.ToString());

    }

}

运行结果

True

SQL方式,连接字符串是server=.;database=db;uid=sa;pwd=sa 2007-1-22 8:21:44





OK

[源码下载]