编辑6.1. 简介
IResource接口位于Spring.Core.IO命名空间中,可以用统一的方式描述和访问不同类型的资源。通过该接口,可以用类似多态的、与协议无关的方式处理文件和URL资源——.NET的FCL中没有具备这些功能的接口。IResource接口继承自IInputStream接口,后者只有一个属性:Stream InputStream,IResource又其基础上添加了一系列属性用来描述资源的信息。
顶部编辑6.2. IResource接口
IResource接口的定义如下所示:
public interface IResource : IInputStreamSource
{
bool IsOpen { get; }
Uri Uri { get; }
FileInfo File { get; }
string Description { get; }
bool Exists { get; }
IResource CreateRelative(string relativePath);
}
表6.1. IResource接口的属性| 属性 | 解释 |
|---|
| InputStream | 继承自IInputStream接口。打开并返回一个System.IO.Stream。每次读取都会返回新的Stream,调用者必须负责Stream的关闭工作。 |
| Exists | 检查资源是否存在,如果不存在就返回false。 |
| IsOpen | 返回一个布尔值,以表明该资源是否一个已经打开的流。如果返回true,则InputStream属性就不能多次读取,只能是读取一次然后关闭,以防资源泄漏。IResource接口的实现类,除了InputStreamResource,其它都应该将该属性返回false。 |
| Description | 返回对资源的描述,比如说完整的文件名或实际的URL。 |
| Uri | 资源的Uri表示形式。 |
| File | 如果资源可以被解析为一个绝对的文件路径,就返回一个System.IO.FileInfo。 |
IResource接口只有一个方法:
表 6.2. IResource接口的方法| 方法 | 解释 |
|---|
| IResource CreateRelative(string relativePath) | 使用类似于相对路径的字符串(./ 和 ../)创建与当前资源相关的资源 |
实现类可以用该方法获取一个代表实际URL或File的IResource对象,但要保证能够处理这些类型的资源。
在Spring.NET的内部大量使用了IResource接口,一般都是作为参数传递给需要使用IResource的方法。还有一些方法(比如 IApplicationContext实现类的构造器),可以接受字符串类型的参数,并用该参数的值在内部创建一个IResource的实例。
实际上,在开发中我们也可以把IResource接口作为一个非常有用的工具类型,应用程序代码可以只使用IResource来访问资源,不需要引用Spring.NET的其它部分。虽然这样作会使代码依赖Spring.NET,但也仅仅是依赖几个小小的工具类而已,不防就把它当成是一个用来解决小问题的第三方类库。
顶部
编辑6.3. 内置的IResource实现类
Spring.NET内置的IResource实现类包括:
- AssemblyResource:用于访问内嵌在.NET程序集中的资源。相应的Uri格式为:assembly://<AssemblyName>/<NameSpace>/<ResourceName>。
- ConfigSectionResource:用于处理.NET应用程序配置文件(即App.Config)中与Spring.NET有关的配置数据,Uri格式为:config://<path to section>
- FileSystemResource:访问文件系统资源,Uri格式为:file://<filename>
- InputStreamResource:用于包装一个原始的System.IO.Stream对象。不支持Uri格式。
- UriResource:通过诸如http等标准的协议访问资源。Uri格式即对应的标准协议格式。
相关内容可参考MSDN文档supported Uri scheme types。
顶部
编辑6.4. IResourceLoader接口
要从指定的Uri中载入资源,需要使用相应的IResourceLoader实现类。默认情况下Spring.NET使用的是 ConfigurableResourceLoader。通常不需要直接访问该类,因为IAppicationContext自己也扩展了 IResourceLoader接口。IResourceLoader接口只有一个方法:IResource GetResource(string loaction)。IApplicationContext将该方法委托给ConfigurableResourceLoader类代理,可以支持上面列出的各种Uri格式。如果未在Uri中指定协议类型则使用文件协议。请看下面的例子:
IResource resource = appContext.GetResource("http://www.springframework.net/license.html");
resource = appContext.GetResource("assembly://Spring.Core.Tests/Spring/TestResource.txt");
resource = appContext.GetResource("https://sourceforge.net/");
resource = appContext.GetResource("file:///C:/WINDOWS/ODBC.INI");
StreamReader reader = new StreamReader(resource.InputStream);
Console.WriteLine(reader.ReadToEnd());
通过创建新的IResource实现类可以注册新的协议,但要保证新类的构造器能够正确解析Uri字符串。在Spring.Web命名空间中,有一个使用Server.MapPath来解析资源文件名的例子,可以参考一下。
CreateRelative方法允许使用相对路径载入资源。对于相对的程序集资源(按:relative assembly resources)来说,使用相对路径可以根据程序集的命名空间来载入资源,例如:
IResource res = new AssemblyResource("assembly://Spring.Core.Tests/Spring/TestResource.txt");
IResource res2 = res.CreateRelative("./Core.IO/TestIOResource.txt");
这段代码首先载入资源文件TestResource.txt,然后转到Spring.Core.IO命名空间下,载入其中的资源文件TestIOResource.txt。
编辑6.5. IResourceLoaderAware接口
IResourceLoaderAware是一个特殊的接口,实现该接口的对象可以获取一个IResourceLoader引用。
public interface IResourceLoaderAware
{
IResourceLoader ResourceLoader
{
set;
get;
}
}
应用程序上下文会自动判断布署在其中的对象是否实现了IResourceLoaderAware接口。如果对象实现了该接口,应用程序上下文会将自己的引用传递给该属性(别忘了应用程序上下文也实现了IResourceLoader接口)。
当然了,既然IApplicationContext扩展了IResourceLoader接口,我们就完全可以用 IApplicationcontextAware接口先获取应用程序上下文,再去访问资源。不过一般来说,如果我们只需要 IResourceLoader的功能,还是单独使用IResourceLoaderAware接口比较好。代码只需要与IResourceLoader 接口耦合,无需理会整个应用程序上下文。
顶部
编辑6.6. 应用程序上下文和IResource路径
某些IApplicationContext实现类的构造器可以用字符串或字符串数组类型的参数来表示XML文件路径。例如,下面的代码使用两个XML文件创建了XMLApplicationContext:
IApplicationContext context = new XmlApplicationContext(
"file://objects.xml", "assembly://MyAssembly/MyProject/objects-dal-layer.xml");
顶部