.NET的资源并不限于.resx文件,你可以采用任意存储“.NET研究”形式 [下篇]

简介:   在《上篇》中我们谈到ResourceManager在默认的情况下只能提供对内嵌于程序集的.resources资源文件的存取。为了实现对独立二进制.resources资源文件的支持,我们自定义了BinaryResoruceNManager。

  在《上篇》中我们谈到ResourceManager在默认的情况下只能提供对内嵌于程序集的.resources资源文件的存取。为了实现对独立二进制.resources资源文件的支持,我们自定义了BinaryResoruceNManager。在本篇中我们还将创建两个自定义的ResourceManager,以实现对独立.resx资源文件和自定义结构的XML资源文件的支持。(文中的例子从这里下载)

一、自定义ResXResourceManager实现对.Resx资源文件的支持
二、将资源定义在自定义结构的XML文件中
三、为XML资源存储形式定义ResourceReader和ResourceWriter
四、为XML资源存储形式定义ResourceSet
五、为XML资源存储形式定义ResourceManager
六、补充

  一、自定义ResXResourceManager实现对.Resx资源文件的支持

  较之.resources资源文件这种二进制文件,以XML形式定义的.Resx资源文件是一个纯文本文件,我们可以对其进行自由地修改,所以有时候我们直接将独立的.resx文件作为资源存储形式更利于资源内容的维护。在《上篇》中我们创建了自定义的BinaryResourceManager实现了对独立.resources资源文件的支持,这里我们仅仅需要采用相似的方式定义一个ResXResourceManager。由于.NET已经提供了支持.Resx资源文件的ResourceSet、ResourceReader和ResourceWriter,所以ResXResourceManager和BinaryResourceManager一样简单,下面是其全部定义。

 
   
public class ResXResourceManager : FileResourceManager
{
public ResXResourceManager( string directory, string baseName)
:
base (directory, baseName, 上海闵行企业网站制作 " .resx " )
{}

protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
return new ResXResourceSet( this .GetResourceFileName(culture));
}
}

  .resx文件对应的ReourceSet为ResXResourceSet,定义在System.Windows.Forms程序集中,所以在重写的InternalGetResourceSet中我们只需要返回这么一个ResXResourceSet即可。ResXResourceSet对应的ResourceReader为ResXResourceReader,而.resx文件可以通过ResXResourceWriter进行写入。

  既然我们的ResXResourceManager已经创建好了,我们就可以将它应用到我们的演示程序中。演示代码如下所示,三个辅助方法PrepareFiles、AddResource和DisplayResource的实现可以参考《上篇》,后面列出的是与之前的演示完全一样的输出结果。

 
   
PrepareFiles( " GreetingMessages " , " resx上海徐汇企业网站制作an>");

AddResource(()
=> new ResXResourceWriter("GreetingMessages.resx"), new CultureInfo("en-US"));
AddResource(()
=> new ResXResourceWriter("GreetingMessages.en-US.resx"), new CultureInfo("en-US"));
AddResource(()
=> new ResXResourceWriter("GreetingMessages.zh-CN.resx"), new CultureInfo("zh-CN"));

DisplayResource(
new ResXResourceManager("", "GreetingMessages"));

  输出结果:

 
 
English (United States)
Merry Christmas
!
Happy Chinese New Year
!

Chinese (Simplified, PRC)
圣诞快乐
!
新年快乐
!

Japanese (Japan)
Merry Christmas
!
Happy Chinese New Year
!

  二、将资源定义在自定义结构的XML文件中

  .Resx资源文件本质上就是一XML文件,既然.Resx文件可以作为资源文件,我们肯定可以将资源定义在我们自定义的XML文件中。由于仅仅是作为演示,我尽可能简化这个XML的结构,并且仅仅提供纯文本资源内容的支持。我们自定义XML资源文件具有如下的结构:

 
   
<? xml version="1.0" encoding="utf-8" ?>
< resources >
< add name ="Greeting4Chris" value ="Merry Christmas!" />
< add name ="Greeting4NewYear" value ="Happy Chinese New Year!" />
</ resources >

  《上篇》中讲到,.NET的资源体系包含4个重要的对象,它们分别是ResourceManager、ResourceSet、ResourceReader和ResourceWriter。要实现将自定义结构的XML作为资源文件,我们需要自定义这四个类型。

  三、为XML资源存储形式定义ResourceReader和ResourceWriter

  我定义了如下一个XmlResourceReader作为读取XML资源文件的ResourceWriter。XmlResourceReader实现接口IResourceReader,在构造函数中将资源内容从XML文件中读取出来保存在一个XmlDocument对象中。在GetEnumerator方法中将该XmlDocument得内容转换成一个Hashtable,并返回该Hashtable的Enumerator。

 
   
public class XmlResourceReader: IResourceReader
{
public XmlDocument Document { get ; private set ; }
public XmlResourceReader( string fileName)
{
this .Document = new XmlDocument();
this .Document.Load(fileName);
}
public XmlResourceReader(Stream stream)
{
this .Document = new XmlDocument();
this .Document.Load(stream);
}
public IDictionaryEnumerator GetEnumerator()
{
Dictionary
< string , string > set = new Dictionary < string , string > ();
foreach (XmlNode item in this .Document.GetElementsByTagName( " add " ))
{
set .Add(item.Attributes[ " name " ].Value, item.Attributes[ " value " ].Value);
}
return set .GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Dispose(){}
public void Close(){}
}

  将资源内容写入XML文件的实现定义在如下一个名为XmlResourceWriter的文件中,它实现接口IResourceWriter。上面说过我们的XML仅仅提供对于纯文本内容的支持,在这里我们仅仅实现了value参数类型为string的AddResource方法。XmlResourceWriter的逻辑很简单,仅仅涉及到对于XmlDocument节点的添加和保存,所以在这里无需再多作介绍了。

 
 
ublic class XmlResourceWriter: IResourceWriter
{
public XmlDocument Document { get ; private set ; }
private string fileName;
private XmlElement root;

public XmlResourceWriter( string fileName)
{
this .fileName = fileName;
this .Document = new XmlDocument();
this .Document.AppendChild( this .Document.CreateXmlDeclaration( " 1.0 " , " utf-8 " , null ));
this .root = this .Document.CreateElement( " resources " );
this .Document.AppendChild( this .root);
}

public void AddResource( string name, byte [] value)
{
throw new NotImplementedE上海企业网站设计与制作xception();
}

public void AddResource( string name, object value)
{
throw new NotImplementedException();
}

public void上海网站建设an> AddResource(string name, string value)
{
var node
= this.Document.CreateElement(上海企业网站制作>"add");
node.SetAttribute(
"name", name);
node.SetAttribute(
"value", value);
this.root.AppendChild(node);
}

上海闵行企业网站设计与制作"color: #0000ff;">public void Generate()
{
using (XmlWriter writer = new XmlTextWriter(this.fileName, Encoding.UTF8))
{
this.Document.WriteTo(writer);
}
}
public void Dispose(){}
public void Close() { }
}

  四、为XML资源存储形式定义ResourceSet

  ResourceReader和ResourceWriter已经创建完毕,现在我们来创建自定义的ResourceSet:XmlResorceSet。我们定义的XmlResourceReader在构造函数中被实例化,在ReadResource方法执行过程中,它将被用于完成资源内容的读取操作,读取的结果最终用于初始化该XmlResuorceSet对象。

 
   
public class XmlResourceSet : ResourceSet
{
public XmlResourceSet(Stream stream)
{
this .Reader = new XmlResourceReader(stream);
this .Table = new Hashtable();
this .ReadResources();
}
public XmlResourceSet( string fileName)
{
base .Reader = new XmlResourceReader(fileName);
base .Table = new Hashtable();
this .ReadResources();
}
public override Type GetDefaultReader()
{
return typeof (XmlResourceReader);
}
public override Type GetDefaultWriter()
{
return typeof (XmlResourceWriter);
}
}

  五、为XML资源存储形式定义ResourceManager

  最后一部自然是创建我们自定义的ResourceManager:XmlResourceManager。和之前创建的BinaryResourceManager、ResXResourceManager一样,我们只需要重写InternalGetResourceSet方法,返回相应的ResourceSet对象即可,在这里返回的自然是上面创建的XmlResourceSet。

 
   
public class XmlResourceManager: FileResourceManager
{
public XmlResourceManager( string directory, string baseName)
:
base (directory, baseName, " .xml " )
{}

protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
return new XmlResourceSet( this .GetResourceFileName(culture));
}
}

  将XmlResourceManager放进我们的演示程序,你依然可以得到一样的结果

 
   
PrepareFiles( " GreetingMessages " , " xml " );

AddResource(()
=> new XmlResourceWriter( " GreetingMessages.xml " ), new CultureInfo( " en-US " ));
AddResource(()
=> new XmlResourceWriter( " GreetingMessages.en-US.xml " ), new CultureInfo( " en-US " ));
AddResource(()
=> new XmlResourceWriter( " GreetingMessages.zh-CN.xml " ), new CultureInfo( " zh-CN " ));

DisplayResource(
new XmlResourceManager( "" , " GreetingMessages " ));

  执行结果:

 
   
English (United States)
Merry Christmas
!
Happy Chinese New Year
!

Chinese (Simplified, PRC)
圣诞快乐
!
新年快乐
!

Japanese (Japan)
Merry Christmas
!
Happy Chinese New Year
!

  六、补充

  XmlResourceManager的定义仅仅为你提供了一种实现自定义资源存储形式的解决方案,按照一样的思路,你可以采用其他的资源存储形式,比较有价值的应该是将资源内容定义在数据库表中。在分布式架构中,你甚至可以通过远程调用服务的方式来获取资源,不过在这种情况下,你应该考虑进行相应的缓存机制提升性能。

目录
相关文章
|
3月前
|
人工智能 机器人
D1net阅闻 | 谷歌DeepMind研究发现LLM新特性
D1net阅闻 | 谷歌DeepMind研究发现LLM新特性
|
5月前
|
Linux C# Windows
.NET使用MiniWord高效生成Word文件
.NET使用MiniWord高效生成Word文件
143 12
|
6月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
77 4
|
6月前
Visual Studio 快速分析 .NET Dump 文件
【11月更文挑战第10天】.NET Dump 文件是在 .NET 应用程序崩溃或出现问题时生成的,记录了应用程序的状态,包括内存对象、线程栈和模块信息。通过分析这些文件,开发人员可以定位和解决内存泄漏、死锁等问题。在 Visual Studio 中,可以通过调试工具、内存分析工具和符号加载等功能来详细分析 Dump 文件。此外,还可以使用第三方工具如 WinDbg 进行更深入的分析。
280 1
|
7月前
|
数据库连接 开发者
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第15天】在.NET中,有两种有效的资源释放方式:一是使用`using`语句,适用于实现`IDisposable`接口的对象,如文件流、数据库连接等,能确保资源及时释放,避免泄漏;二是手动调用`Dispose`方法并处理异常,提供更灵活的资源管理方式,适用于复杂场景。这两种方式都能有效管理资源,提高应用性能和稳定性。
166 2
|
7月前
|
算法 Java 数据库连接
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第14天】在 .NET 中,`IDisposable` 接口提供了一种标准机制来释放非托管资源,如文件句柄、数据库连接等。此类资源需手动释放以避免泄漏。实现 `IDisposable` 的类可通过 `Dispose` 方法释放资源。使用 `using` 语句可确保资源自动释放。此外,.NET 的垃圾回收器会自动回收托管对象所占内存,提高程序效率。示例代码展示了如何使用 `MyFileHandler` 类处理文件操作并释放 `FileStream` 资源。
127 2
|
7月前
|
C# Windows
一款基于.NET开发的简易高效的文件转换器
一款基于.NET开发的简易高效的文件转换器
|
8月前
.NET 压缩/解压文件
【9月更文挑战第5天】在 .NET 中,可利用 `System.IO.Compression` 命名空间进行文件的压缩与解压。首先引入相关命名空间,然后通过 GZipStream 类实现具体的压缩或解压功能。下面提供了压缩与解压文件的方法示例及调用方式,便于用户快速上手操作。
|
5月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
124 5
|
8月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
131 7