原文很长,为了便于阅读和理解,特将该文章改写成通俗易懂而且内容精炼的中文.
预备知识:系统默认的处理资源和本地化的方法是使用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() { } } 完毕。 本人没有测试过,待测试通过,献上最精炼的源代码.敬请稍候. |
|
|
|