zoukankan      html  css  js  c++  java
  • 建立自定义的数据驱动的本地化资源provider

    建立自定义的数据驱动的本地化资源provider

    转自http://www.west-wind.com/presentations/wwdbresourceprovider/
    作者:Rick Strahl.
    改写:于宏伟
    关键词:asp.net 资源,本地化, resource provider,resx.

    本文探讨了自定义的本地化资源提供者.如果想用一个可替代系统的资源处理方案,例如把所有的资源放入数据库中,而不是放在分散的资源文件里,你可以自定义一个resource provider.
    原文很长,为了便于阅读和理解,特将该文章改写成通俗易懂而且内容精炼的中文.

    预备知识:系统默认的处理资源和本地化的方法是使用resx文件存储资源.

    要使用自定义的resource provider,需要2个步骤:
     a) 修改web.config 文件,以便系统使用自定义的资源提供者
     b) 建立自定义资源提供者类,最少包括3个:
          1.ResourceProviderFactory,工厂类,用来建立ResourceProvider对象.
      2.ResourceProvider,实现IResourceProvider,IImplicitResourceProvider,IwwResourceProvider 接口.
      3.ResourceReader 实现IResourceReader.
     

    修改web.config 文件,以使用自定义的资源提供者。

    <configuration>
      <system.web>
        <globalization resourceProviderFactoryType="Westwind.Globalization.DbSimpleResourceProviderFactory,Westwind.Globalization" />
      </system.web>
    </configuration>


    建立自定义资源提供者类:
    1.工厂类
    [DesignTimeResourceProviderFactoryAttribute(typeof(DbDesignTimeResourceProviderFactory))]
    public class DbSimpleResourceProviderFactory : ResourceProviderFactory
    {
       
        public override IResourceProvider CreateGlobalResourceProvider(string classname)
        {
            return new DbSimpleResourceProvider(null, classname);
        }
     
      
        public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
        {
           
            string ResourceSetName = DbResourceConfiguration.Current.StripVirtualPath(virtualPath);
            return new DbSimpleResourceProvider(null,ResourceSetName.ToLower());
        }
    }

    2.提供者类
    public class DbSimpleResourceProvider : IResourceProvider, IImplicitResourceProvider
    {  
       
        private string _ResourceSetName;       
     
     
        private IDictionary _resourceCache;
     

        private DbSimpleResourceProvider()
        { }
     

        public DbSimpleResourceProvider(string virtualPath, string className)
        {
            _ResourceSetName = className;           
        }
     

      
        private IDictionary GetResourceCache(string cultureName)
        {
            if (cultureName == null)
                cultureName = "";
     

            if (this._resourceCache == null)
                this._resourceCache = new ListDictionary();
     

            IDictionary Resources = this._resourceCache[cultureName] as IDictionary;
            if (Resources == null)
            {
                // *** DEPENDENCY HERE (#1): Using DbResourceDataManager to retrieve resources
     

                // *** Use datamanager to retrieve the resource keys from the database
                DbResourceDataManager Data = new DbResourceDataManager();
                Resources = Data.GetResourceSet(cultureName as string, this._ResourceSetName);
                this._resourceCache[cultureName] = Resources;
            }
     

            return Resources;
        }  
     

      
        public void ClearResourceCache()
        {
            this._resourceCache.Clear();
        }
     

       
        object IResourceProvider.GetObject(string ResourceKey, CultureInfo Culture)
        {
            string CultureName = null;
            if (Culture != null)
                CultureName = Culture.Name;
            else
                CultureName = CultureInfo.CurrentUICulture.Name;
     

            return this.GetObjectInternal(ResourceKey, CultureName);
        }
     

       
        object GetObjectInternal(string ResourceKey, string CultureName)
        {
            IDictionary Resources = this.GetResourceCache(CultureName);
           
            object value = null;          
            if (Resources == null)
                value = null;
            else
                value = Resources[ResourceKey];
                           
            // *** If we're at a specific culture (en-Us) and there's no value fall back
            // *** to the generic culture (en)
            if (value == null && CultureName.Length > 3)
            {
                // *** try again with the 2 letter locale
                return GetObjectInternal(ResourceKey,CultureName.Substring(0,2) );
            }
     

            // *** If the value is still null get the invariant value
            if (value == null)
            {
                Resources = this.GetResourceCache("");
                if (Resources == null)
                  value = null;
                else
                  value = Resources[ResourceKey];
            }
     

            // *** If the value is still null and we're at the invariant culture
            // *** let's add a marker that the value is missing
            // *** this also allows the pre-compiler to work and never return null
            if (value == null && string.IsNullOrEmpty(CultureName))
            {
                // *** No entry there
                value = "";
     

                // *** DEPENDENCY HERE (#2): using DbResourceConfiguration and DbResourceDataManager to optionally
                //                           add missing resource keys
     

                // *** Add a key in the repository at least for the Invariant culture
                // *** Something's referencing but nothing's there
                if (DbResourceConfiguration.Current.AddMissingResources)
                    new DbResourceDataManager().AddResource(ResourceKey, value.ToString(), "", this._ResourceSetName);               
     

            }
     

            return value;
        }


    3.Reader类

    public class DbSimpleResourceReader : IResourceReader
    {
        private IDictionary _resources;
     

        public DbSimpleResourceReader(IDictionary resources)
        {
            _resources = resources;
        }
        IDictionaryEnumerator IResourceReader.GetEnumerator()
        {
            return _resources.GetEnumerator();
        }
        void IResourceReader.Close()
        {
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return _resources.GetEnumerator();
        }
        void IDisposable.Dispose()
        {
        }
    }
     
    完毕。
    本人没有测试过,待测试通过,献上最精炼的源代码.敬请稍候.

  • 相关阅读:
    vue 使用print.js实现前端打印功能
    lin UI微信小程序组件库
    将博客搬至CSDN
    第20节:Java集合框架 【多测师_王sir】
    第19节:Java三大特性-多态之接口 【多测师_王sir】
    第18节:Java练习题 【多测师_王sir】
    第17节:Java三大特性-继承之重写 【多测师_王sir】
    第16节:Java练习题【多测师_王sir】
    第15节:Java三大特性【多测师_王sir】
    第14节:Java练习题【多测师_王sir】
  • 原文地址:https://www.cnblogs.com/brucepark/p/1758906.html
Copyright © 2011-2022 走看看