建立自定義的數(shù)據(jù)驅(qū)動(dòng)的本地化資源provider
更新時(shí)間:2010年06月17日 13:56:13 作者:
本文探討了自定義的本地化資源提供者.如果想用一個(gè)可替代系統(tǒng)的資源處理方案,例如把所有的資源放入數(shù)據(jù)庫(kù)中,而不是放在分散的資源文件里,你可以自定義一個(gè)resource provider.
原文很長(zhǎng),為了便于閱讀和理解,特將該文章改寫(xiě)成通俗易懂而且內(nèi)容精煉的中文.
預(yù)備知識(shí):系統(tǒng)默認(rèn)的處理資源和本地化的方法是使用resx文件存儲(chǔ)資源.
要使用自定義的resource provider,需要2個(gè)步驟:
a) 修改web.config 文件,以便系統(tǒng)使用自定義的資源提供者
b) 建立自定義資源提供者類(lèi),最少包括3個(gè):
1.ResourceProviderFactory,工廠類(lèi),用來(lái)建立ResourceProvider對(duì)象.
2.ResourceProvider,實(shí)現(xiàn)IResourceProvider,IImplicitResourceProvider,IwwResourceProvider 接口.
3.ResourceReader 實(shí)現(xiàn)IResourceReader.
修改web.config 文件,以使用自定義的資源提供者。
<configuration>
<system.web>
<globalization resourceProviderFactoryType="Westwind.Globalization.DbSimpleResourceProviderFactory,Westwind.Globalization" />
</system.web>
</configuration>
建立自定義資源提供者類(lèi):
1.工廠類(lèi)
[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.提供者類(lèi)
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類(lèi)
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()
{
}
}
完畢。
本人沒(méi)有測(cè)試過(guò),待測(cè)試通過(guò),獻(xiàn)上最精煉的源代碼.敬請(qǐng)稍候.
預(yù)備知識(shí):系統(tǒng)默認(rèn)的處理資源和本地化的方法是使用resx文件存儲(chǔ)資源.
要使用自定義的resource provider,需要2個(gè)步驟:
a) 修改web.config 文件,以便系統(tǒng)使用自定義的資源提供者
b) 建立自定義資源提供者類(lèi),最少包括3個(gè):
1.ResourceProviderFactory,工廠類(lèi),用來(lái)建立ResourceProvider對(duì)象.
2.ResourceProvider,實(shí)現(xiàn)IResourceProvider,IImplicitResourceProvider,IwwResourceProvider 接口.
3.ResourceReader 實(shí)現(xiàn)IResourceReader.
修改web.config 文件,以使用自定義的資源提供者。
復(fù)制代碼 代碼如下:
<configuration>
<system.web>
<globalization resourceProviderFactoryType="Westwind.Globalization.DbSimpleResourceProviderFactory,Westwind.Globalization" />
</system.web>
</configuration>
建立自定義資源提供者類(lèi):
1.工廠類(lèi)
復(fù)制代碼 代碼如下:
[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.提供者類(lèi)
復(fù)制代碼 代碼如下:
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類(lèi)
復(fù)制代碼 代碼如下:
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()
{
}
}
完畢。
本人沒(méi)有測(cè)試過(guò),待測(cè)試通過(guò),獻(xiàn)上最精煉的源代碼.敬請(qǐng)稍候.
相關(guān)文章
微信公眾平臺(tái)開(kāi)發(fā)之語(yǔ)音識(shí)別.Net代碼解析
這篇文章主要為大家詳細(xì)解析了微信公眾平臺(tái)開(kāi)發(fā)之語(yǔ)音識(shí)別.Net代碼,感興趣的小伙伴們可以參考一下2016-06-06詳解Asp.Net母版頁(yè)元素ID不一致的體現(xiàn)
由于總體排版和設(shè)計(jì)的需要,我們往往創(chuàng)建母版頁(yè)來(lái)實(shí)現(xiàn)整個(gè)網(wǎng)站的統(tǒng)一性,這篇文章主要介紹了詳解Asp.Net母版頁(yè)元素ID不一致的體現(xiàn),感興趣的小伙伴們可以參考一下2018-11-11asp.net core標(biāo)簽助手的高級(jí)用法TagHelper+Form
這篇文章主要為大家詳細(xì)介紹了asp.net core標(biāo)簽助手的高級(jí)用法TagHelper+Form,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07ASP.NET Internet安全Forms身份驗(yàn)證方法
安全性是 ASP.NET Web 應(yīng)用程序中一個(gè)非常重要的方面,它涉及內(nèi)容非常廣泛,不能在一篇文章內(nèi)說(shuō)明所有的安全規(guī)范,本文講述如何利用IIS以及Forms 身份驗(yàn)證構(gòu)建安全的 ASP.NET 應(yīng)用程序,它是目前被使用最多最廣的驗(yàn)證/授權(quán)方式.2009-12-12MVC+EasyUI+三層新聞網(wǎng)站建立 主頁(yè)布局的方法(五)
這篇文章主要為大家詳細(xì)介紹了MVC+EasyUI+三層新聞網(wǎng)站建立的第五篇,教大家如何進(jìn)行主頁(yè)布局,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07ASP.NET中實(shí)現(xiàn)導(dǎo)出ppt文件數(shù)據(jù)的實(shí)例分享
這篇文章主要介紹了ASP.NET中實(shí)現(xiàn)導(dǎo)出ppt文件數(shù)據(jù)的實(shí)例分享,實(shí)例代碼用C#語(yǔ)言編寫(xiě),利用.NET的庫(kù)實(shí)現(xiàn)起來(lái)還是比較簡(jiǎn)潔的,需要的朋友可以參考下2016-02-02