Asp.net2.0中的提供程序---dashcommerce中的税率计算提供程序

本文介绍ASP.NET中的税率计算模块实现,重点讲解了自定义提供程序的应用,包括在线支付与税率计算模块的配置与实例化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

  commerce starter kit (commerce Starter kit 随书 asp.net2.0典型项目开发 ---应用篇光盘中的一套程序,他改自dashcommerce) 中,有很多自定义提供程序的应用,比方在线支付模块,税率计算模块等,

 

 在网站App_Code/Services/TaxProvider/下面是相关的代码实现

 

 首先是配置节的代码,来自文件:TaxServiceSection.cs

 

namespace Commerce.Providers
{

 

    public class TaxServiceSection : ConfigurationSection
    {
        [ConfigurationProperty("providers")]
        public ProviderSettingsCollection Providers
        {
            get { return (ProviderSettingsCollection)base["providers"]; }
        }

        [StringValidator(MinLength = 1)]
        [ConfigurationProperty("defaultProvider",
            DefaultValue = "SqlTaxProvider")]
        public string DefaultProvider
        {
            get { return (string)base["defaultProvider"]; }
            set { base["defaultProvider"] = value; }
        }


 
 
    }
}

这里声明了TaxServiceSection类,这个类有一个DefaultProvider属性,以及一个Providers集合属性,集合属性使用的.net框架提供的ProviderSettingsCollection类,对于这个类大家应该不陌生,像MemberShip,RoleManager 配置节里的Providers就是对应这个类的,ProviderSettingsCollection 是ProviderSettings的集合类,ProviderSettings 继承于ConfigurationElement, ProviderSetttings 里面定义了一个name ,跟type属性,而Parameters 属性是一个NameValueCollection 类型的,应此如Membership 配置提供程序中(<providers><add name="" type="" .... /></providers>的其他属性如connectionStringName,enablePasswordRetrieval等多是保存在Parameters中的,参考下面的membership节

 

  <membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15" hashAlgorithmType="">
   <providers>
    <clear/>
    <add connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="CSK" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" passwordStrengthRegularExpression="" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
   </providers>
  </membership>

 

 

 TaxServiceSection 在配置文件中对应的声明如下

 <section name="TaxService" type="Commerce.Providers.TaxServiceSection" allowDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="false"/>

 

 具体的配置如下

 <TaxService defaultProvider="StrikeIronTaxProvider">
  <providers>
   <clear />
   <add serviceKey=""   name="StrikeIronTaxProvider" type="Commerce.Providers.StrikeIronTaxProvider" />
  </providers>
 </TaxService>

 

 

 以上是TaxServiceSection的介绍,TaxServiceSection的作用就是从web.config中读取配置数据,

 下面我们来看TaxProvider类,由于各地计算税率的方法不同因此这里把TaxProvider类声明为一个抽象类

  public abstract class TaxProvider : ProviderBase ,这个类继承自ProviderBase,ProviderBase是所有使用提供程序模型类的基类.在TaxProvider类中定义了一些属性如ServiceLogin,ServiceKey等,另外重要的是定义的三个抽象方法如下

        public abstract decimal GetTaxRate(string zip);
        public abstract decimal GetTaxRate(Commerce.Common.USState state);
        public abstract DataSet GetTaxTable(Commerce.Common.USState state);

 这三个抽象方法在具体的TaxProvider类中被实现,Commerce starter kit 给出了三个TaxProvider类的具体实现,他们是 StrikeIronTaxProvider.cs,FlatRateTaxProvider.cs以及ZeroTaxRateProvider.cs.

以StrikeIronTaxProvider为例, 里面首先是实现了 public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) 方法,这个方法是必需实现的,因为Provider被实例化后,需要设置一些属性,而这些属性就是保存在web.config相应配置节中<providers>元素中的<add .../>元素中的属性,

下面这段代码摘自StrikeIronTaxprovider.cs中的Initialize方法

 

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);
            try
            {
                this.ServiceKey = config["serviceKey"].ToString();
                //this.ServicePassword = config["servicePassword"].ToString();
                //this.ServiceLogin = config["serviceLogin"].ToString();
            }
            catch
            {
                throw new Exception("The Service Key must be set for the StrikeIronTaxProvider to work");
            }

        }

 

 提供程序模型提供了通过配置来替换具体实现类的编程模型,应此提供程序会通过反射机制来架载,具体实例化的时间是,对于应类被第一次调用时实例化,一般情况下只实例化一次. TaxService.cs文件中定义的TaxService类,封装了TaxProvider类的使用,他对外提供一组静态方法,将具体的TaxProvider类实例保存在静态字段中

 private static TaxProvider _provider = null,静太字段对应类的生命周期等同于应用程序的周期(Asp.net 的 Application  )

下面是这个类的代码:

 

 public class TaxService
    {
        #region Provider-specific bits
        private static TaxProvider _provider = null;
        private static object _lock = new object();

        public TaxProvider Provider
        {
            get { return _provider; }
        }

        public static TaxProvider Instance
        {
            get
            {
                LoadProviders();
                return _provider;
            }
        }
        private static void LoadProviders()
        {
            // Avoid claiming lock if providers are already loaded
            if (_provider == null)
            {
                lock (_lock)
                {
                    // Do this again to make sure _provider is still null
                    if (_provider == null)
                    {
                        // Get a reference to the <TaxServiceSection> section
                        TaxServiceSection section = (TaxServiceSection)
                            WebConfigurationManager.GetSection
                            ("TaxService");

                        // Only want one provider here
                         _provider = (TaxProvider)ProvidersHelper.InstantiateProvider
                            (section.Providers[0], typeof(TaxProvider));

                       
                        if (_provider == null)
                            throw new ProviderException
                                ("Unable to load default TaxProvider");
                    }
                }
            }
        }
        #endregion


        public static decimal CalculateAmountByZIP(string zipCode, decimal subTotal) {
            decimal dOut = 0;
   try {
    decimal dRate = Instance.GetTaxRate(zipCode);
    dOut = subTotal * dRate;
   } catch(Exception x) {
    throw new ApplicationException("Tax calculation failed: " + x.Message, x);
   }
            return dOut;
        }
        public static decimal GetUSTaxRate(string zipCode)
        {
            return Instance.GetTaxRate(zipCode);

        }
        public static decimal GetUSTaxRate(Commerce.Common.USState state)
        {
            return Instance.GetTaxRate(state);
        }
    }

 

我们注意到LoadProviders()方法中使用双lock语句来保证只实例化一个TaxProvider 的具体类(具体看配置文件),LoadProviders()中首先获取TaxServieceSection 节中的配置数据

         // Get a reference to the <TaxServiceSection> section
  TaxServiceSection section = (TaxServiceSection)WebConfigurationManager.GetSection("TaxService");

 接着是实例化

                        // Only want one provider here
                         _provider = (TaxProvider)ProvidersHelper.InstantiateProvider
                            (section.Providers[0], typeof(TaxProvider));

这里使用ProvidersHelper.InstantiateProvider() 方法

 

 下面是通过Reflector 找到的实现代码

 

public static class ProvidersHelper
{
    // Methods
    [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
    public static ProviderBase InstantiateProvider(ProviderSettings providerSettings, Type providerType)
    {
        ProviderBase base2 = null;
        try
        {
            string str = (providerSettings.Type == null) ? null : providerSettings.Type.Trim();
            if (string.IsNullOrEmpty(str))
            {
                throw new ArgumentException(SR.GetString("Provider_no_type_name"));
            }
            Type c = ConfigUtil.GetType(str, "type", providerSettings, true, true);
            if (!providerType.IsAssignableFrom(c))
            {
                throw new ArgumentException(SR.GetString("Provider_must_implement_type", new object[] { providerType.ToString() }));
            }
            base2 = (ProviderBase) HttpRuntime.CreatePublicInstance(c);
            NameValueCollection parameters = providerSettings.Parameters;
            NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal);
            foreach (string str2 in parameters)
            {
                config[str2] = parameters[str2];
            }
            base2.Initialize(providerSettings.Name, config);
        }
        catch (Exception exception)
        {
            if (exception is ConfigurationException)
            {
                throw;
            }
            throw new ConfigurationErrorsException(exception.Message, providerSettings.ElementInformation.Properties["type"].Source, providerSettings.ElementInformation.Properties["type"].LineNumber);
        }
        return base2;
    }

    [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
    public static void InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType)
    {
        foreach (ProviderSettings settings in configProviders)
        {
            providers.Add(InstantiateProvider(settings, providerType));
        }
    }
}

 

 注意红色的代码,这几行代码的功能是通过反射实例化类,并且将ProviderSettings中的Parameters属性复制到config中,

完成后调用ProviderBase的initialize方法, base2.Initialize(providerSettings.Name, config);

 

 //===================

internal static object CreateNonPublicInstance(Type type, object[] args)
{
    return Activator.CreateInstance(type, BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, args, null);
}

最终调用的是 Activator.CreateInstance方法

 

 

内容概要:该PPT详细介绍了企业架构设计的方法论,涵盖业务架构、数据架构、应用架构和技术架构四大核心模块。首先分析了企业架构现状,包括业务、数据、应用和技术四大架构的内容和关系,明确了企业架构设计的重要性。接着,阐述了新版企业架构总体框架(CSG-EAF 2.0)的形成过程,强调其融合了传统架构设计(TOGAF)和领域驱动设计(DDD)的优势,以适应数字化转型需求。业务架构部分通过梳理企业级和专业级价值流,细化业务能力、流程和对象,确保业务战略的有效落地。数据架构部分则遵循五大原则,确保数据的准确、一致和高效使用。应用架构方面,提出了分层解耦和服务化的设计原则,以提高灵活性和响应速度。最后,技术架构部分围绕技术框架、组件、平台和部署节点进行了详细设计,确保技术架构的稳定性和扩展性。 适合人群:适用于具有一定企业架构设计经验的IT架构师、项目经理和业务分析师,特别是那些希望深入了解如何将企业架构设计与数字化转型相结合的专业人士。 使用场景及目标:①帮助企业和组织梳理业务流程,优化业务能力,实现战略目标;②指导数据管理和应用开发,确保数据的一致性和应用的高效性;③为技术选型和系统部署提供科学依据,确保技术架构的稳定性和扩展性。 阅读建议:此资源内容详尽,涵盖企业架构设计的各个方面。建议读者在学习过程中,结合实际案例进行理解和实践,重点关注各架构模块之间的关联和协同,以便更好地应用于实际工作中。
资 源 简 介 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系, 详 情 说 明 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。 本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系,在此基础上重点分析了一种快速ICA实现算法一FastICA。物质的非线性荧光谱信号可以看成是由多个相互独立的源信号组合成的混合信号,而这些独立的源信号可以看成是光谱的特征信号。为了更好的了解光谱信号的特征,本文利用独立分量分析的思想和方法,提出了利用FastICA算法提取光谱信号的特征的方案,并进行了详细的仿真实验。 此外,我们还进行了进一步的研究,探索了其他可能的ICA应用领域,如音乐信号处理、图像处理以及金融数据分析等。通过在这些领域中的实验和应用,我们发现ICA在提取信号特征、降噪和信号分离等方面具有广泛的潜力和应用前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值