建立自定义的数据驱动的本地化资源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 were at a specific culture (en-Us) and theres 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 were at the invariant culture // *** lets 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 // *** Somethings referencing but nothings 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() { } } 完毕 。 本人没有测试过,待测试通过,献上最精炼的源代码.敬请稍候. |