379 lines
14 KiB
XML
379 lines
14 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
/*
|
|
* Copyright 2002-2010 the original author or authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
-->
|
|
<chapter xml:id="resources" xmlns="http://docbook.org/ns/docbook" version="5">
|
|
<title>Resources</title>
|
|
|
|
<section xml:id="objects-iresource">
|
|
<title>Introduction</title>
|
|
|
|
<para>The <literal>IResource</literal> interface contained in the
|
|
<literal>Spring.Core.IO</literal> namespace provides a common interface to
|
|
describe and access data from diverse resource locations. This abstraction
|
|
lets you treat the <literal>InputStream</literal> from a file and from
|
|
a URL in a polymorphic and protocol-independent manner... the .NET BCL
|
|
does not provide such an abstraction. The <literal>IResource</literal>
|
|
interface inherits from <literal>IInputStream</literal> that provides a
|
|
single property <literal>Stream InputStream</literal>. The
|
|
<literal>IResource</literal> interface adds descriptive information about
|
|
the resource via a number of additional properties. Several
|
|
implementations for common resource locations, i.e. file, assembly, uri,
|
|
are provided and you may also register custom IResource
|
|
implementations.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>The <literal>IResource</literal> interface</title>
|
|
|
|
<para>The IResource interface is shown below</para>
|
|
|
|
<programlisting language="csharp">public interface IResource : IInputStreamSource
|
|
{
|
|
bool IsOpen { get; }
|
|
|
|
Uri Uri { get; }
|
|
|
|
FileInfo File { get; }
|
|
|
|
string Description { get; }
|
|
|
|
bool Exists { get; }
|
|
|
|
IResource CreateRelative(string relativePath);
|
|
}</programlisting>
|
|
|
|
<table frame="all">
|
|
<title>IResource Properties</title>
|
|
|
|
<tgroup cols="2">
|
|
<colspec colname="c1" colwidth="2*" />
|
|
|
|
<colspec colname="c2" colwidth="5*" />
|
|
|
|
<thead>
|
|
<row>
|
|
<entry>Property</entry>
|
|
|
|
<entry>Explanation</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>InputStream</literal></entry>
|
|
|
|
<entry>Inherited from IInputStream. Opens and returns a
|
|
<literal>System.IO.Stream</literal>. It is expected that each
|
|
invocation returns a fresh Stream. It is the responsibility of the
|
|
caller to close the stream.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>Exists</literal></entry>
|
|
|
|
<entry>returns a boolean indicating whether this resource actually
|
|
exists in physical form.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>IsOpen</literal></entry>
|
|
|
|
<entry>returns a boolean indicating whether this resource
|
|
represents a handle with an open stream. If true, the InputStream
|
|
cannot be read multiple times, and must be read once only and then
|
|
closed to avoid resource leaks. Will be false for all usual
|
|
resource implementations, with the exception of
|
|
<literal>InputStreamResource</literal>.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>Description</literal></entry>
|
|
|
|
<entry>Returns a description of the resource, such as the fully
|
|
qualified file name or the actual URL.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>Uri</literal></entry>
|
|
|
|
<entry>The Uri representation of the resource.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>File</literal></entry>
|
|
|
|
<entry>Returns a <literal>System.IO.FileInfo</literal> for
|
|
this resource if it can be resolved to an absolute file
|
|
path.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>and the methods</para>
|
|
|
|
<table frame="all">
|
|
<title>IResource Methods</title>
|
|
|
|
<tgroup cols="2">
|
|
<colspec colname="c1" colwidth="2*" />
|
|
|
|
<colspec colname="c2" colwidth="5*" />
|
|
|
|
<thead>
|
|
<row>
|
|
<entry>Method</entry>
|
|
|
|
<entry>Explanation</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>IResource CreateRelative (string
|
|
relativePath)</literal></entry>
|
|
|
|
<entry>Creates a resource relative to this resource using relative
|
|
path like notation (./ and ../).</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>You can obtain an actual URL or File object representing the
|
|
resource if the underlying implementation is compatible and supports that
|
|
functionality.</para>
|
|
|
|
<para>The Resource abstraction is used extensively in Spring itself, as an
|
|
argument type in many method signatures when a resource is needed. Other
|
|
methods in some Spring APIs (such as the constructors to various
|
|
<literal>IApplicationContext</literal> implementations), take
|
|
a String which is used to create a Resource appropriate to that context
|
|
implementation</para>
|
|
|
|
<para>While the Resource interface is used a lot with Spring and by
|
|
Spring, it's actually very useful to use as a general utility class by
|
|
itself in your own code, for access to resources, even when your code
|
|
doesn't know or care about any other parts of Spring. While this couples
|
|
your code to Spring, it really only couples it to this small set of
|
|
utility classes and can be considered equivalent to any other library you
|
|
would use for this purpose</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Built-in IResource implementations</title>
|
|
|
|
<para>The resource implementations provided are <itemizedlist
|
|
spacing="compact">
|
|
<listitem>
|
|
|
|
|
|
<literal>AssemblyResource</literal>
|
|
|
|
accesses data stored as .NET resources inside an assembly. Uri syntax is
|
|
|
|
<literal>assembly://<AssemblyName>/<NameSpace>/<ResourceName></literal>
|
|
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
|
|
<literal>ConfigSectionResource</literal>
|
|
|
|
accesses Spring.NET configuration data stored in a custom configuration section in the .NET application configuration file (i.e. App.config). Uri syntax is
|
|
|
|
<literal>config://<path to section></literal>
|
|
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
|
|
<literal>FileSystemResource</literal>
|
|
|
|
accesses file system data. Uri syntax is
|
|
|
|
<literal>file://<filename></literal>
|
|
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
|
|
<literal>InputStreamResource</literal>
|
|
|
|
a wrapper around a raw
|
|
|
|
<literal>System.IO.Stream</literal>
|
|
|
|
. Uri syntax is not supported.
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
|
|
<literal>UriResource</literal>
|
|
|
|
accesses data from the standard System.Uri protocols such as http and https. In .NET 2.0 you can use this also for the ftp protocol. Standard Uri syntax is supported.
|
|
</listitem>
|
|
</itemizedlist> Refer to the MSDN documentation for more information on
|
|
<ulink
|
|
url="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemurimemberstopic.asp">supported
|
|
Uri scheme types</ulink>.</para>
|
|
|
|
<section>
|
|
<title>Registering custom IResource implementations</title>
|
|
|
|
<para>The configuration section handler,
|
|
<literal>ResourceHandlersSectionHandler</literal>, is used to
|
|
register any custom <literal>IResource</literal>
|
|
implementations you have created. In the configuration section you list
|
|
the type of <literal>IResource</literal> implementation and
|
|
the protocol prefix. Your custom
|
|
<literal>IResource</literal> implementation must provide a
|
|
constructor that takes a string as it's sole argument that represents
|
|
the URI string. Refer to the SDK documentation for
|
|
<literal>ResourceHandlersSectionHandler</literal> for more
|
|
information. An example of the
|
|
<literal>ResourceHandlersSectionHandler</literal> is shown below for
|
|
a fictional <literal>IResource</literal> implementation that
|
|
interfaces with a database.</para>
|
|
|
|
<programlisting language="myxml"><configuration>
|
|
<configSections>
|
|
<sectionGroup name="spring">
|
|
|
|
<section name='context' type='Spring.Context.Support.ContextHandler, Spring.Core'/>
|
|
|
|
<section name="resourceHandlers"
|
|
type="Spring.Context.Support.ResourceHandlersSectionHandler, Spring.Core"/>
|
|
|
|
</sectionGroup>
|
|
</configSections>
|
|
|
|
<spring>
|
|
|
|
<resourceHandlers>
|
|
<handler protocol="db" type="MyCompany.MyApp.Resources.MyDbResource, MyAssembly"/>
|
|
</resourceHandlers>
|
|
|
|
<context>
|
|
<resource uri="db://user:pass@dbName/MyDefinitionsTable"/>
|
|
</context>
|
|
|
|
</spring>
|
|
</configuration></programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>The <literal>IResourceLoader</literal></title>
|
|
|
|
<para>To load resources given their Uri syntax, an implementation of the
|
|
<literal>IResourceLoader</literal> is used. The default implementation
|
|
is <literal>ConfigurableResourceLoader</literal>. Typically you will
|
|
not need to access this class directly since the
|
|
<literal>IApplicationContext</literal> implements the
|
|
<literal>IResourceLoader</literal> interface that contains the single
|
|
method <literal>IResource GetResource(string location)</literal>. The
|
|
provided implementations of <literal>IApplicationContext</literal>
|
|
delegate this method to an instance of
|
|
<literal>ConfigurableResourceLoader</literal> which supports the Uri
|
|
protocols/schemes listed previously. If you do not specify a protocol then
|
|
the file protocol is used. The following shows some sample
|
|
usage.<programlisting language="csharp">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());</programlisting> Other protocols can be
|
|
registered along with a new implementations of an IResource that must
|
|
correctly parse a Uri string in its constructor. An example of this can be
|
|
seen in the <literal>Spring.Web</literal> namespace that uses
|
|
<literal>Server.MapPath</literal> to resolve the filename of a
|
|
resource.</para>
|
|
|
|
<para>The <literal>CreateRelative</literal> method allows you to easily
|
|
load resources based on a relative path name. In the case of relative
|
|
assembly resources, the relative path navigates the namespace within an
|
|
assembly. For example: <programlisting language="csharp">IResource res = new AssemblyResource("assembly://Spring.Core.Tests/Spring/TestResource.txt");
|
|
IResource res2 = res.CreateRelative("./IO/TestIOResource.txt");</programlisting>
|
|
This loads the resource <literal>TestResource.txt</literal> and then
|
|
navigates to the <literal>Spring.Core.IO</literal> namespace and loads the
|
|
resource <literal>TestIOResource.txt</literal></para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>The <literal>IResourceLoaderAware</literal>
|
|
interface</title>
|
|
|
|
<para>The <literal>IResourceLoaderAware</literal> interface is
|
|
a special marker interface, identifying objects that expect to be provided
|
|
with a <literal>IResourceLoader</literal> reference.</para>
|
|
|
|
<programlisting language="csharp">public interface IResourceLoaderAware
|
|
{
|
|
IResourceLoader ResourceLoader
|
|
{
|
|
set;
|
|
get;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>When a class implements
|
|
<literal>IResourceLoaderAware</literal> and is deployed into
|
|
an application context (as a Spring-managed object), it is recognized as
|
|
<literal>IResourceLoaderAware</literal> by the application
|
|
context. The application context will then invoke the ResourceLoader
|
|
property, supplying itself as the argument (remember, all application
|
|
contexts in Spring implement the
|
|
<literal>IResourceLoader</literal> interface).</para>
|
|
|
|
<para>Of course, since an
|
|
<literal>IApplicationContext</literal> is a
|
|
<literal>IResourceLoader</literal>, the object could also
|
|
implement the <literal>IApplicationContextAware</literal>
|
|
interface and use the supplied application context directly to load
|
|
resources, but in general, it's better to use the specialized
|
|
<literal>IResourceLoader</literal> interface if that's all
|
|
that's needed. The code would just be coupled to the resource loading
|
|
interface, which can be considered a utility interface, and not the whole
|
|
Spring <literal>IApplicationContext</literal>
|
|
interface.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Application contexts and <literal>IResource</literal>
|
|
paths</title>
|
|
|
|
<para>An application context constructor (for a specific application
|
|
context type) generally takes a string or array of strings as the location
|
|
path(s) of the resource(s) such as XML files that make up the definition
|
|
of the context. For example, you can create an XmlApplicationContext from
|
|
two resources as follows:</para>
|
|
|
|
<programlisting language="csharp">IApplicationContext context = new XmlApplicationContext(
|
|
"file://objects.xml", "assembly://MyAssembly/MyProject/objects-dal-layer.xml");
|
|
</programlisting>
|
|
</section>
|
|
</chapter> |