# Windows Services

## Remarks

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 (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 `examples\Spring\Spring.Examples.WindowsService` to better understand the package. Please check the Spring.NET website for the latest updates to this document.

## Introduction

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.

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.

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.

The executable that at present provides these features is the `Spring.Services.WindowsService.Process.exe` assembly. It makes heavy use of classes and interfaces definde in the `Spring.Services.WindowsService.Common.dll` assembly. You should reference the common assembly it if you want to follow the advice on customization contained in the following sections

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 .

## The `Spring.Services.WindowsService.Process.exe` application

### Installing

The installation can be done in two ways, using the .NET SDK `installutil.exe` tool or using the more mundane `Spring.Services.WindowsService.Installer.exe`; 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.

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)

That said, while `installutil` is documented on its own , the command line for `Spring.Services.WindowsService.Installer.exe` is as follow:

    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

for example, to install, you can invoke it with the following:

    ... install  Spring.Services.WindowsService.Process.exe "Spring.Service Support" spring-service

and to uninstall it:

    ... uninstall  spring-service

### Configuration

The standard .NET `.config` file can be used to tune some parameters of `Spring.Services.WindowsService.Process.exe`, (including log4net settings, for which it is recomended to consult the log4net documentation).

This file also define the context run by this process; here the file in its current beauty:

    <configuration>

        <configSections>
            <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
            <sectionGroup name="spring">
                <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
                <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
            </sectionGroup>
        </configSections>

        <spring>
            <context type="Spring.Context.Support.XmlApplicationContext, Spring.Core">
                <resource uri="file://~/service-process-definition.xml" />
            </context>
        </spring>

        <system.runtime.remoting>
        <application>
            <channels>
            <channel ref="http" port="1234" />
            </channels>
        </application>
        </system.runtime.remoting>

      <log4net>
        <!-- see http://logging.apache.org/log4net/release/manual/introduction.html -->
        <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d [%t] %-5p %c{1} - %m%n" />
          </layout>
          <file value="logs/Spring.Service.Process.log" />
          <appendToFile value="true" />
          <maximumFileSize value="500KB" />
          <maxSizeRollBackups value="5" />
        </appender>
        <appender name="OutputDebugString" type="log4net.Appender.OutputDebugStringAppender">
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d{HH:mm:ss,fff} %-5p %c{2}(line:%L) - %m%n" />
          </layout>
        </appender>
        <root>
          <level value="OFF" />
        </root>
          <logger name="Spring.Services">
              <level value="ALL" />
          <appender-ref ref="RollingFile" />
          <appender-ref ref="OutputDebugString" />
          </logger>
      </log4net>

    </configuration>

As you see, the context is defined in another file: let's review the objects it defines.

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 `IObjectFactoryPostProcessor` and so will be automatically applied to this application context: