fixes for daily build target
misc updates to ref documentation use signed NNS assembly based on spring.net key sync vs.net 2003 solution
This commit is contained in:
@@ -1,441 +0,0 @@
|
||||
<%@ CodeTemplate %>
|
||||
<%@ Assembly Name="System.Web" %>
|
||||
<%@ Import Namespace="System.IO" %>
|
||||
<%@ Import Namespace="System.Xml" %>
|
||||
<%@ Import Namespace="System.Web" %>
|
||||
<%@ Import Namespace="System.Text" %>
|
||||
|
||||
<%@ Assembly Name="AgileDocs.Core" %>
|
||||
<%@ Import Namespace="AgileDocs.Core" %>
|
||||
|
||||
|
||||
<script runat="template">
|
||||
|
||||
string XmlExample (string fileName, string xpath)
|
||||
{
|
||||
return "<programlisting format='linespecific'>"
|
||||
+ XmlPeek.HtmlEncode (
|
||||
XmlPeek.ExtractAndQueryXPath(fileName, xpath,
|
||||
new ExtractXml("<!--@", "@-->")))
|
||||
+ "</programlisting>";
|
||||
}
|
||||
|
||||
string CsExample (string fileName, string xpath)
|
||||
{
|
||||
return "<programlisting format='linespecific'>"
|
||||
+ XmlPeek.HtmlEncode (
|
||||
XmlPeek.ExtractAndQueryXPath(fileName, xpath,
|
||||
new ExtractXml("////", null)))
|
||||
+ "</programlisting>";
|
||||
}
|
||||
|
||||
string EntireFile (string fileName)
|
||||
{
|
||||
return "<programlisting format='linespecific'>"
|
||||
+ XmlPeek.HtmlEncode (
|
||||
XmlPeek.GetFileContent(fileName))
|
||||
+ "</programlisting>";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<chapter id="windows-service">
|
||||
<title>Windows Services</title>
|
||||
|
||||
<sect1>
|
||||
<title>Remarks</title>
|
||||
<para>
|
||||
This is functionality that will be included after the
|
||||
1.0 release. If you want to use these features please get the
|
||||
code from CVS <ulink url="http://opensource.atlassian.com/confluence/spring/display/NET/Project+Structure"></ulink>
|
||||
(instructions) or from the download section of the Spring.NET website that contains an
|
||||
.zip with the full CVS tree.
|
||||
In addition to this documentation
|
||||
you can refer to the example program located at
|
||||
<literal>examples\Spring\Spring.Examples.WindowsService</literal>
|
||||
to better understand the package. Please check the Spring.NET
|
||||
<ulink url="http://www.springframework.net/doc/reference/windows-service.html">website</ulink>
|
||||
for the latest updates to this document.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
Developers usually create Windows Services using the
|
||||
Visual Studio .NET wizard. While not difficult to do, this
|
||||
procedure is repetative and does not encourage separation between
|
||||
infrastructure code (windows service) and application code. This is
|
||||
generally considered a "bad thing" but you can certainly disagree.
|
||||
</para>
|
||||
<para>
|
||||
As Spring.NET can provide an explicitly managed
|
||||
initialize/destroy lifecycle for singleton objects, there is
|
||||
a natural synergy with the lifecycle of a Windows service.
|
||||
As such, it could be very convenient to expose a Spring application
|
||||
context as a Windows service. Starting and stopping the service corresponds
|
||||
to creating and destroying an application context and its
|
||||
contained objects. This approach provides a high level means to
|
||||
declare what objects are created and destroyed when developing
|
||||
a Windows service.
|
||||
</para>
|
||||
<para>
|
||||
To do that, Spring.NET requires the installation of one physical
|
||||
service able to run as services as many applications as you want - each a
|
||||
logical independent service in their own application domain.
|
||||
By default, the deployment and updating of the service can also
|
||||
be done by copying the relevant executables to a special directory.
|
||||
</para>
|
||||
<para>
|
||||
The executable that at present provides these features is the
|
||||
<literal>Spring.Services.WindowsService.Process.exe</literal>
|
||||
assembly. It makes heavy use of classes and interfaces definde in
|
||||
the <literal>Spring.Services.WindowsService.Common.dll</literal>
|
||||
assembly. You should reference the common assembly it if you want to
|
||||
follow the advice on customization contained in the following sections
|
||||
</para>
|
||||
<para>
|
||||
The benefits of this approach, a part from those given by separating
|
||||
infrastructure code and application code (a field where Spring.NET
|
||||
tries hard to succeed) is that you can think about installing a new
|
||||
service at client site by simply dropping a new application assembly
|
||||
in a remote directory<footnote></footnote>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The <literal>Spring.Services.WindowsService.Process.exe</literal> application</title>
|
||||
<sect2>
|
||||
<title>Installing</title>
|
||||
<para>
|
||||
The installation can be done in two ways, using the .NET SDK
|
||||
<literal>installutil.exe</literal> tool or using the more mundane
|
||||
<literal>Spring.Services.WindowsService.Installer.exe</literal>;
|
||||
while the former is the standard, the latter is probably
|
||||
more flexible. It allows you to customize the name/display name of the
|
||||
service and has the ability to install multiple times the same assembly
|
||||
with different names. This can be useful in a
|
||||
number of scenarios, especially where you don't like, for some
|
||||
reasons, to run several different logical services under the
|
||||
same physical windows service.
|
||||
</para>
|
||||
<para><emphasis>
|
||||
Be aware of the fact that the service will be installed as
|
||||
running with the system account (installing with a specific
|
||||
user account seems a bit buggy on Windows XP)
|
||||
</emphasis></para>
|
||||
<para>
|
||||
That said, while <literal>installutil</literal>
|
||||
<ulink url="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconinstallerutilityinstallutilexe.asp">
|
||||
<citetitle>is documented on its own </citetitle></ulink>,
|
||||
the command line for
|
||||
<literal>Spring.Services.WindowsService.Installer.exe</literal>
|
||||
is as follow:
|
||||
<programlisting format='linespecific'>Spring.Services.WindowsService.Installer.exe
|
||||
|
||||
usage:
|
||||
install service-exe-path service-display-name service-name
|
||||
uninstall service-name [i|u] service-exe-path service-display-name service-name</programlisting>
|
||||
for example, to install, you can invoke it with the following:
|
||||
<programlisting format='linespecific'>... install Spring.Services.WindowsService.Process.exe "Spring.Service Support" spring-service</programlisting>
|
||||
and to uninstall it:
|
||||
<programlisting format='linespecific'>... uninstall spring-service</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Configuration</title>
|
||||
<para>
|
||||
The standard .NET <literal>.config</literal> file
|
||||
can be used to tune some parameters of
|
||||
<literal>Spring.Services.WindowsService.Process.exe</literal>,
|
||||
(including log4net settings, for which it is recomended to consult
|
||||
the log4net documentation).
|
||||
</para>
|
||||
<para>
|
||||
This file also define the context run by this process; here the file in its current beauty:
|
||||
<%= XmlExample("src/Spring/Spring.Services/App.config", "code") %>
|
||||
</para>
|
||||
<para>
|
||||
As you see, the context is defined in another file: let's review the objects it defines.
|
||||
</para>
|
||||
<para>
|
||||
Firstly, it is worth notice that in order to 'localize' the service (i.e. to know where it is installed to use that directory as
|
||||
base for the deploy dir as in the above file) you should define an object like this: the name is not
|
||||
very important, it is important that it is an <classname>IObjectFactoryPostProcessor</classname> and so will be
|
||||
automatically applied to this application context:
|
||||
<%= XmlExample("src/Spring/Spring.Services/WindowsService/Process/service-process-definition.xml", "code/localizer") %>
|
||||
</para>
|
||||
<para>
|
||||
In that object definition you can customize the prefix for the following string
|
||||
<%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Localizer.cs", "code/process.format") %>
|
||||
but you usually won't need it; the default value is
|
||||
<%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Localizer.cs", "code/localizer.def.prefix") %>
|
||||
</para>
|
||||
<para>
|
||||
The sole important object defined by this context, i.e. the main object run by the service.
|
||||
The thing you can (and should) configure is the path to the folder you will use as the deploy location;
|
||||
the current definition, to avoid the need for a fully qualified path (e.g.: <literal>c:\spring\services</literal>) uses
|
||||
the properties made available by the <literal>localizer</literal> above:
|
||||
<%= XmlExample("src/Spring/Spring.Services/WindowsService/Process/service-process-definition.xml", "code/service") %>
|
||||
</para>
|
||||
<para>
|
||||
The above object is then easily remoted using spring remoting utilities (please notice you should tune the remoting configuration
|
||||
listed in the standard .NET <literal>.config</literal> file, listed above):
|
||||
<%= XmlExample("src/Spring/Spring.Services/WindowsService/Process/service-process-definition.xml", "code/remoted.service") %>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Running an application context as a windows service</title>
|
||||
<para>
|
||||
If you package an application using the layout and
|
||||
conventions described here, you'll be able to run an
|
||||
application context as a Windows Service.
|
||||
The conventions used are modeled after those used by ASP.NET
|
||||
and are very easy to follow.
|
||||
</para>
|
||||
<para>
|
||||
As already said, you'll have a Spring.NET application context running in
|
||||
a dedicated <literal>AppDomain</literal> hosted in a process running
|
||||
as a windows service: that process is able to run many application contexts
|
||||
simultaneously.
|
||||
</para>
|
||||
<para>A complete application runable as service consists of a
|
||||
directory containing:
|
||||
<itemizedlist spacing="compact">
|
||||
|
||||
<listitem>
|
||||
<para>The .NET configuration file
|
||||
<literal>service.config</literal>:
|
||||
this file should define your application context.
|
||||
Moreover this files will be used
|
||||
by the CLR to configure the application domain
|
||||
your application will run in, exactly as you expect.
|
||||
This file has the same role of ASP.NET <literal>Web.config</literal>
|
||||
file.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Optional: an xml context file (<literal>watcher.xml</literal>)
|
||||
defining the watcher for your application.</para>
|
||||
<para>The watcher controls the automatic redeployment of the
|
||||
service and is discussed more in the following section.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Recomended: along the lines of ASP.NET convention, a <literal>bin</literal>
|
||||
subdirectory containing all
|
||||
the assemblies your application needs; you can of course put
|
||||
your assemblies in the same directory where you put
|
||||
<literal>service.config</literal> but this is not encouraged ...
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<sect2>
|
||||
<title><literal>service.config</literal></title>
|
||||
<para>
|
||||
This is the standard .NET configuration file for the
|
||||
<literal>AppDomain</literal> that will host your application. It is
|
||||
semantically equivalent to the ASP.NET <literal>Web.config</literal>
|
||||
file.
|
||||
<footnote>
|
||||
<para>
|
||||
<literal>log4net</literal> users please notice that (as
|
||||
of 1.2 beta 9) file appenders, when dealing with a relative
|
||||
file name, assume it is relative to the application
|
||||
domain code base. If you use log4net, it is very handy with the mechanics used by
|
||||
Spring Windows Service as every log file you will specify will
|
||||
be relative the directory containing the service application.
|
||||
</para>
|
||||
</footnote>
|
||||
</para>
|
||||
<para>
|
||||
This file should also define your application context. When the
|
||||
service is started and stopped, the corresponding lifecycle methods
|
||||
are called on all the singletons defined. Of course, singletons are
|
||||
automatically instantiated by the application context when the
|
||||
service starts. For more information on lifecycles in Spring.NET see
|
||||
<xref linkend="objects-factory-lifecycle"/>
|
||||
Here an example taken from the tests:
|
||||
<%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Echo/service.config", "code") %>
|
||||
</para>
|
||||
<para>
|
||||
In this case the context is (again!) defined in another file (author's personal taste...) and the only 'service' is the
|
||||
<literal>echo</literal> object (there is also a <literal>PropertyPlaceholderConfigurer</literal> just to make the example
|
||||
more realistic):
|
||||
<%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Echo/service.xml", "code") %>
|
||||
</para>
|
||||
<sect3>
|
||||
<title>Let the application know where it is</title>
|
||||
<para>
|
||||
There are some properties you may need at runtime, when your services
|
||||
will run, and you cannot know in advance. Hopefully, your xml
|
||||
definition file will allow to find the information it needs using some
|
||||
predefined variables you can use inside the service definition file
|
||||
with the standard
|
||||
NAnt style <literal>${property name}</literal> syntax.</para>
|
||||
<para>These properies are:
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para><literal>spring.services.application.fullpath</literal>
|
||||
that will be replaced with the full path of the application's
|
||||
<literal>AppDomain.BaseDirectory</literal>, i.e., where your
|
||||
application has been deployed;</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>spring.services.application.name</literal> that
|
||||
will be replaced with the name of the subdirectory where the
|
||||
application has been deployed. Each application is deployed in
|
||||
its own directory, of course;</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
These properties are accessible only if one defines a localizer in the
|
||||
context like this (the localizer is a special <literal>IObjectFactoryPostProcessor</literal>:
|
||||
<%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Simple/service.xml", "code/localizer") %>
|
||||
</para>
|
||||
<para>
|
||||
As you can see above, one can easily change the prefix used by that localizer and then write someting like:
|
||||
<%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Simple/service.xml", "code/simple") %>
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title><literal>watcher.xml</literal> - optional</title>
|
||||
<para>
|
||||
This file allows you to optionally define a watcher for your application
|
||||
that can automatically redeploy it when needed.
|
||||
</para>
|
||||
<para>
|
||||
The important thing to notice is that you can define your own
|
||||
application watcher, named <literal>watcher</literal>. Here it is used
|
||||
a watcher that listen for changes on the filesystem, configured to
|
||||
listen for some changes and to ignore others.
|
||||
</para>
|
||||
<para>
|
||||
You can provide your own implementation defining an object named
|
||||
<literal>watcher</literal> that implements
|
||||
<literal>Spring.Services.WindowsService.Common.Deploy.IApplicationWatcher</literal>:
|
||||
<%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Deploy/IApplicationWatcher.cs", "code/interface") %>
|
||||
</para>
|
||||
<para>
|
||||
Please notice that this interface is currently a movable target and
|
||||
will probably change before the first official release (this will probably
|
||||
affect also the way a watcher will know about the application it should
|
||||
monitor, as shown in a few lines).
|
||||
</para>
|
||||
<para>A tipical example of this file is give here:
|
||||
<%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Cassini/watcher.xml", "code") %>
|
||||
</para>
|
||||
<para>
|
||||
As you can see, if you need it, you can reference the
|
||||
<literal>Spring.Services.WindowsService.Common.IApplication</literal>
|
||||
object that your watcher should watch using the name
|
||||
<literal>.injected.application</literal>.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title><literal>bin</literal> directory - optional</title>
|
||||
<para>
|
||||
This is, by default, the folder where your assemblies are placed
|
||||
in the same way they are in an ASP.NET application.
|
||||
</para>
|
||||
<para>
|
||||
Putting assemblies there is more a convention and maybe a good
|
||||
practice (they are isolated from other artifacts, but maybe you will
|
||||
prefer to use another directory (modify the
|
||||
<literal>service.config</literal> file accordingly) or the application
|
||||
directory directly (= <literal>bin</literal> parent).
|
||||
</para>
|
||||
<para>
|
||||
Be aware of the fact that the process in which your application will
|
||||
run will have its own PATH environmental variable. As such
|
||||
don't expect to be successfull using dlls imported
|
||||
with [DllImport] if they are not in the system PATH of the
|
||||
hosting machine: while it is well known that the CLR fusion
|
||||
algorithm will not consider the PATH variable, you may be biten
|
||||
by assemblies using non-system dlls (SQLite and Firebird ADO.NET
|
||||
providers are good examples).
|
||||
</para>
|
||||
<para>Reiterating, one can put assemblies in another directory
|
||||
under the application directory tree, and write
|
||||
the .NET configuration file (<literal>service.config</literal>)
|
||||
accordingly: .NET probing algorithm is always in place.
|
||||
</para>
|
||||
<para>
|
||||
Please notice that it is not required that
|
||||
your application uses or include any of the Spring.NET assemblies:
|
||||
any object in any assembly, given it has lifecycle methods, can
|
||||
be run as a service: non invasive infrastructure support courtesy
|
||||
of Spring.NET!
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Customizing or extending</title>
|
||||
<para>
|
||||
It should be said that support for windows service has been initially
|
||||
developed with a clear but limited set of 'extension points' in mind,
|
||||
mainly related to the way you can deploy your services:
|
||||
deploy location (filesystem, zip archives, mailbox, urls, ...),
|
||||
(auto-)updating features, and so on.
|
||||
</para>
|
||||
<para>
|
||||
To better understand the following discussion, the following figure
|
||||
depicts some of the inner details of
|
||||
<literal>Spring.Services.WindowsService.Process.exe</literal>
|
||||
at run-time:
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata align="center"
|
||||
fileref="images/spring.windows-service.png" format="png"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>Spring.Services.WindowsService.Process.exe run-time details</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</para>
|
||||
<sect2>
|
||||
<title>The <literal>.config</literal> file</title>
|
||||
</sect2>
|
||||
<para>
|
||||
The executable <literal>Spring.Services.WindowsService.Process.exe</literal>
|
||||
is somewhat configured by the corresponding
|
||||
<literal>.config</literal> file.
|
||||
Please notice that this file is the most important extension point
|
||||
for windows service support, and it will probably be made more powerful
|
||||
and flexible in the future.
|
||||
</para>
|
||||
<para>
|
||||
For applications deployed in the standard way (i.e. on the filesystem
|
||||
as explained above) the updating features are configured by the
|
||||
<literal>watcher.xml</literal> file, <emphasis>if present</emphasis>,
|
||||
as already seen.
|
||||
</para>
|
||||
<para>
|
||||
There should be however, other ways to deploy your applications,
|
||||
maybe just as zip files dropped somewhere on the web or sent via
|
||||
e-mail.
|
||||
</para>
|
||||
<para>
|
||||
For these scenarios, your deploy location will be something that
|
||||
implements
|
||||
<literal>Spring.Services.WindowsService.Common.Deploy.IDeployLocation</literal>.
|
||||
<para>
|
||||
Please notice that, while questionable, it actually entends
|
||||
<literal>IDisposable</literal> <footnote><para>this has been done
|
||||
as it is possible that a deploy location holds resources that should be
|
||||
released, for example network connections, lock files or the like</para></footnote>:
|
||||
</para>
|
||||
<%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Deploy/IDeployLocation.cs", "code/interface") %>
|
||||
<%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Deploy/IDeployEventSource.cs", "code/interface") %>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user