diff --git a/Spring.Net.2003.sln b/Spring.Net.2003.sln index 63d7a2c3..a58ecbe4 100644 --- a/Spring.Net.2003.sln +++ b/Spring.Net.2003.sln @@ -67,6 +67,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Data.NHibernate12.20 ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Messaging.Nms.2003", "src\Spring\Spring.Messaging.Nms\Spring.Messaging.Nms.2003.csproj", "{C17B27C2-4343-45BA-9A21-73C3CEC19BAD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -213,6 +217,14 @@ Global {2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release.Build.0 = Release|.NET {2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release-1.1.ActiveCfg = Release|.NET {2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release-1.1.Build.0 = Release|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug.ActiveCfg = Debug|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug.Build.0 = Debug|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug-1.1.ActiveCfg = Debug|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug-1.1.Build.0 = Debug|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Release.ActiveCfg = Release|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Release.Build.0 = Release|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Release-1.1.ActiveCfg = Release|.NET + {C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Release-1.1.Build.0 = Release|.NET EndGlobalSection GlobalSection(SolutionItems) = postSolution doc\NamespaceSummary.xml = doc\NamespaceSummary.xml diff --git a/Spring.build b/Spring.build index 02956fd2..68112c1f 100644 --- a/Spring.build +++ b/Spring.build @@ -199,6 +199,7 @@ + @@ -309,7 +310,7 @@ - + @@ -324,7 +325,7 @@ - + @@ -336,6 +337,7 @@ + @@ -343,6 +345,7 @@ depends="set-net-1.1-runtime-configuration, check-spring-basedir, clean-current-bin-dir, TestInit"> + @@ -350,6 +353,7 @@ depends="set-net-2.0-runtime-configuration, check-spring-basedir, clean-current-bin-dir, TestInit"> + @@ -644,10 +648,8 @@ - - + - @@ -695,18 +697,6 @@ - - @@ -778,7 +768,6 @@ - @@ -870,6 +859,8 @@ + + @@ -947,6 +938,8 @@ + + @@ -1016,7 +1009,7 @@ file="src/Spring/Spring.Services/Remoting/Config/spring-remoting-1.1.xsd"/> + file="build-support/install-schema.build"/> diff --git a/doc/reference/src/index.xml b/doc/reference/src/index.xml index fdf2dfe5..8b903cd6 100644 --- a/doc/reference/src/index.xml +++ b/doc/reference/src/index.xml @@ -54,7 +54,7 @@ The Spring.NET Framework Reference Documentation Version 1.1.2 - Last Updated May 6, 2008 + Last Updated June 12, 2008 Mark @@ -288,6 +288,7 @@ &services; &webservices; + VS.NET Integration diff --git a/doc/reference/src/templated/windows-service.xml b/doc/reference/src/templated/windows-service.xml deleted file mode 100644 index 6830dd73..00000000 --- a/doc/reference/src/templated/windows-service.xml +++ /dev/null @@ -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" %> - - - - - - - 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 <literal>Spring.Services.WindowsService.Process.exe</literal> 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: - <%= XmlExample("src/Spring/Spring.Services/App.config", "code") %> - - - 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: - <%= XmlExample("src/Spring/Spring.Services/WindowsService/Process/service-process-definition.xml", "code/localizer") %> - - - 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") %> - - - 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.: c:\spring\services) uses - the properties made available by the localizer above: - <%= XmlExample("src/Spring/Spring.Services/WindowsService/Process/service-process-definition.xml", "code/service") %> - - - The above object is then easily remoted using spring remoting utilities (please notice you should tune the remoting configuration - listed in the standard .NET .config file, listed above): - <%= XmlExample("src/Spring/Spring.Services/WindowsService/Process/service-process-definition.xml", "code/remoted.service") %> - - - - - - Running an application context as a windows service - - 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. - - - As already said, you'll have a Spring.NET application context running in - a dedicated AppDomain hosted in a process running - as a windows service: that process is able to run many application contexts - simultaneously. - - A complete application runable as service consists of a - directory containing: - - - - The .NET configuration file - service.config: - 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 Web.config - file. - - - - - Optional: an xml context file (watcher.xml) - defining the watcher for your application. - The watcher controls the automatic redeployment of the - service and is discussed more in the following section. - - - - Recomended: along the lines of ASP.NET convention, a bin - subdirectory containing all - the assemblies your application needs; you can of course put - your assemblies in the same directory where you put - service.config but this is not encouraged ... - - - - - - <literal>service.config</literal> - - This is the standard .NET configuration file for the - AppDomain that will host your application. It is - semantically equivalent to the ASP.NET Web.config - file. - - - log4net 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. - - - - - 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 - - Here an example taken from the tests: - <%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Echo/service.config", "code") %> - - - In this case the context is (again!) defined in another file (author's personal taste...) and the only 'service' is the - echo object (there is also a PropertyPlaceholderConfigurer just to make the example - more realistic): - <%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Echo/service.xml", "code") %> - - - Let the application know where it is - - 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 ${property name} syntax. - These properies are: - - - spring.services.application.fullpath - that will be replaced with the full path of the application's - AppDomain.BaseDirectory, i.e., where your - application has been deployed; - - - spring.services.application.name 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; - - - - - These properties are accessible only if one defines a localizer in the - context like this (the localizer is a special IObjectFactoryPostProcessor: - <%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Simple/service.xml", "code/localizer") %> - - - 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") %> - - - - - - <literal>watcher.xml</literal> - optional - - This file allows you to optionally define a watcher for your application - that can automatically redeploy it when needed. - - - The important thing to notice is that you can define your own - application watcher, named watcher. Here it is used - a watcher that listen for changes on the filesystem, configured to - listen for some changes and to ignore others. - - - You can provide your own implementation defining an object named - watcher that implements - Spring.Services.WindowsService.Common.Deploy.IApplicationWatcher: - <%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Deploy/IApplicationWatcher.cs", "code/interface") %> - - - 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). - - A tipical example of this file is give here: - <%= XmlExample("test/Spring/Spring.Services.Tests/Data/Spring/WindowsService/Cassini/watcher.xml", "code") %> - - - As you can see, if you need it, you can reference the - Spring.Services.WindowsService.Common.IApplication - object that your watcher should watch using the name - .injected.application. - - - - <literal>bin</literal> directory - optional - - This is, by default, the folder where your assemblies are placed - in the same way they are in an ASP.NET application. - - - 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 - service.config file accordingly) or the application - directory directly (= bin parent). - - - 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). - - Reiterating, one can put assemblies in another directory - under the application directory tree, and write - the .NET configuration file (service.config) - accordingly: .NET probing algorithm is always in place. - - - 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! - - - - - - Customizing or extending - - 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. - - - To better understand the following discussion, the following figure - depicts some of the inner details of - Spring.Services.WindowsService.Process.exe - at run-time: - - - - - - Spring.Services.WindowsService.Process.exe run-time details - - - - - The <literal>.config</literal> file - - - The executable Spring.Services.WindowsService.Process.exe - is somewhat configured by the corresponding - .config 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. - - - For applications deployed in the standard way (i.e. on the filesystem - as explained above) the updating features are configured by the - watcher.xml file, if present, - as already seen. - - - 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. - - - For these scenarios, your deploy location will be something that - implements - Spring.Services.WindowsService.Common.Deploy.IDeployLocation. - - Please notice that, while questionable, it actually entends - IDisposable 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: - - <%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Deploy/IDeployLocation.cs", "code/interface") %> - <%= CsExample("src/Spring/Spring.Services/WindowsService/Common/Deploy/IDeployEventSource.cs", "code/interface") %> - - - - diff --git a/doc/reference/src/transaction.xml b/doc/reference/src/transaction.xml index 1d567dd3..498d4151 100644 --- a/doc/reference/src/transaction.xml +++ b/doc/reference/src/transaction.xml @@ -917,7 +917,7 @@ mgr.DeleteTwoTestObjects("Jack", "Jill"); <objects xmlns="http://www.springframework.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:tx="http://www.springframework.net/schema/tx" + xmlns:tx="http://www.springframework.net/tx" xmlns:db="http://www.springframework.net/database" xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/schema/objects/spring-objects.xsd http://www.springframework.net/schema/tx http://www.springframework.net/schema/tx/spring-tx-1.1.xsd" diff --git a/doc/reference/src/windows-service.xml b/doc/reference/src/windows-service.xml index 470b2acf..682e0066 100644 --- a/doc/reference/src/windows-service.xml +++ b/doc/reference/src/windows-service.xml @@ -172,472 +172,4 @@ usage: 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: - -<!-- provides access to the ${spring.services.process.base.dir} property --> -<object - name="localizer" - type="Spring.Services.WindowsService.Common.Localizer+ForProcess, Spring.Services.WindowsService.Common"> - <!-- change this to access the property with another prefix, for example ${foo.process.base.dir} - <property name="prefix" value="foo"/> - --> -</object> - - - In that object definition you can customize the prefix for the following string - -public static readonly string SpringServicesProcessBaseDirFormat = "{0}.process.base.dir"; - but you usually won't need it; the default value is - -public static readonly string DefaultPrefix = "spring.services"; - - - 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.: c:\spring\services) uses - the properties made available by the localizer above: - -<object - name="service" - type="Spring.Services.WindowsService.Common.DefaultService, Spring.Services.WindowsService.Common" - init-method="Start" - destroy-method="Stop"> - <property name="DeployPath" value="${spring.services.process.base.dir}/deploy"/> -</object> - - - The above object is then easily remoted using spring remoting utilities (please notice you should tune the remoting configuration - listed in the standard .NET .config file, listed above): - -<object name="remoted.service" type="Spring.Remoting.SaoExporter, Spring.Services"> - <property name="TargetName" value="service"/> - <property name="ServiceName" value="SpringWindowsService.rem"/> -</object> - - - - - - Running an application context as a windows service - - 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. - - - As already said, you'll have a Spring.NET application context running in - a dedicated AppDomain hosted in a process running - as a windows service: that process is able to run many application contexts - simultaneously. - - A complete application runable as service consists of a - directory containing: - - - - The .NET configuration file - service.config: - 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 Web.config - file. - - - - - Optional: an xml context file (watcher.xml) - defining the watcher for your application. - The watcher controls the automatic redeployment of the - service and is discussed more in the following section. - - - - Recomended: along the lines of ASP.NET convention, a bin - subdirectory containing all - the assemblies your application needs; you can of course put - your assemblies in the same directory where you put - service.config but this is not encouraged ... - - - - - - <literal>service.config</literal> - - This is the standard .NET configuration file for the - AppDomain that will host your application. It is - semantically equivalent to the ASP.NET Web.config - file. - - - log4net 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. - - - - - 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 - - Here an example taken from the tests: - -<configuration> - - <configSections> - <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> - - <appSettings> - <add key="port" value="10"/> - </appSettings> - - <spring> - <context type="Spring.Context.Support.XmlApplicationContext, Spring.Core"> - <resource uri="file://~/service.xml" /> - </context> - </spring> - -</configuration> - - - In this case the context is (again!) defined in another file (author's personal taste...) and the only 'service' is the - echo object (there is also a PropertyPlaceholderConfigurer just to make the example - more realistic): - -<objects xmlns="http://www.springframework.net" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"> - - <object name="echo" - type="Spring.Services.WindowsService.Samples.Echo, Spring.Services.WindowsService.Tests" - init-method="Start" destroy-method="Stop"> - <property name="port"><value>${port}</value></property> - </object> - - <object id="configurer" type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core"> - <property name="locations"> - <list> - <value>file://~/service.config</value> - </list> - </property> - <property name="configSections"> - <list> - <value>appSettings</value> - </list> - </property> - </object> - -</objects> - - - Let the application know where it is - - 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 ${property name} syntax. - These properies are: - - - spring.services.application.fullpath - that will be replaced with the full path of the application's - AppDomain.BaseDirectory, i.e., where your - application has been deployed; - - - spring.services.application.name 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; - - - - - These properties are accessible only if one defines a localizer in the - context like this (the localizer is a special IObjectFactoryPostProcessor: - -<!-- provides access to the ${spring.services.application.*} properties --> -<object - name="localizer" - type="Spring.Services.WindowsService.Common.Localizer+ForApplication, Spring.Services.WindowsService.Common"> - <!-- change this to access the property with another prefix, for example ${foo.application.base.dir} - --> - <property name="prefix" value="myPrefix"/> -</object> - - - As you can see above, one can easily change the prefix used by that localizer and then write someting like: - -<object name="simple" - type="Spring.Services.WindowsService.Samples.Simple, Spring.Services.WindowsService.Tests" - init-method="Start" destroy-method="Stop"> - <constructor-arg index="0" value="${myPrefix.application.name},${myPrefix.application.fullPath}"/> - <property name="AppName"> - <value>${myPrefix.application.name}</value> - </property> - <property name="AppFullPath"> - <value>${myPrefix.application.fullpath}</value> - </property> -</object> - - - - - - <literal>watcher.xml</literal> - optional - - This file allows you to optionally define a watcher for your application - that can automatically redeploy it when needed. - - - The important thing to notice is that you can define your own - application watcher, named watcher. Here it is used - a watcher that listen for changes on the filesystem, configured to - listen for some changes and to ignore others. - - - You can provide your own implementation defining an object named - watcher that implements - Spring.Services.WindowsService.Common.Deploy.IApplicationWatcher: - -/// <summary> -Interface defining the contract for an application watcher. -<p>An application watcher is responsible to dispatch an -<see cref="IApplicationWatcherFactory">event</see> whenever it thinks the -application has been updated.</p> -<p>Usually it should not raise other kind of events -as they are usually raised by the <see cref="FileSystemApplicationWatcher"/> -that creates the watcher itself</p> -</summary> -<remarks>Usually instances of this interface need to be disposed</remarks> -<seealso cref="DeployEventArgs"/> -<seealso cref="IDeployLocation"/> -<seealso cref="DeployEventType.ApplicationUpdated"/> -<seealso cref="DeployEventAggregator"/> -<seealso cref="IDeployLocation"/> -<seealso cref="DeployEventType"/> -public interface IApplicationWatcher : IDisposable -{ - /// <summary> - /// The watched application - /// </summary> - IApplication Application {get; } - - /// <summary> - /// Start to watch the application, using the given dispatcher to - /// dispatch deply events - /// </summary> - /// <param name="dispatcher">the dispatcher used to raise deploy events</param> - void StartWatching (IDeployEventDispatcher dispatcher); - - /// <summary> - /// Stop to watch the application. - /// </summary> - void StopWatching (); - - /// <summary> - /// If physical events watched by this watcher should be filtered, this methods - /// will allow to set filters that allows and disallows the event to be raised - /// by the watcher. - /// </summary> - /// <param name="allows">the list of allowing filters</param> - /// <param name="disallows">the list of disallowing filters</param> - /// <seealso cref="FilteringSupport"/> - /// <seealso cref="RegularExpressionFilter"/> - void SetFilters (IList allows, IList disallows); -} - - - 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). - - A tipical example of this file is give here: - -<objects> - - <object name='watcher' - type='Spring.Services.WindowsService.Common.Deploy.FileSystem.FileSystemApplicationWatcher'> - <!-- - we can get access to the IApplication we are asked to monitor - using a reference like the following - --> - <constructor-arg ref='.injected.application'/> - - <!-- sometimes the windows OS will decide to not give you the same case you see in explorer: - in fact one should consider this OS case-insensitive with regard to file names ... - The following property, true by default can however be tuned - <property name="ignoreCase" value="false"/> - --> - - <property name="includes"> - <list> - <value>wwwroot/bin/*.*</value> - <value>service.config</value> - <value>service.xml</value> - </list> - </property> - - <!-- - <property name="excludes"> - <list> - <value>Db/**/*.*</value> - <value>Jobs</value> - <value>Jobs</value> - <value>**/*.log</value> - </list> - </property> - --> - - </object> - -</objects> - - - As you can see, if you need it, you can reference the - Spring.Services.WindowsService.Common.IApplication - object that your watcher should watch using the name - .injected.application. - - - - <literal>bin</literal> directory - optional - - This is, by default, the folder where your assemblies are placed - in the same way they are in an ASP.NET application. - - - 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 - service.config file accordingly) or the application - directory directly (= bin parent). - - - 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). - - Reiterating, one can put assemblies in another directory - under the application directory tree, and write - the .NET configuration file (service.config) - accordingly: .NET probing algorithm is always in place. - - - 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! - - - - - - Customizing or extending - - 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. - - - To better understand the following discussion, the following figure - depicts some of the inner details of - Spring.Services.WindowsService.Process.exe - at run-time: - - - - - - Spring.Services.WindowsService.Process.exe run-time details - - - - - The <literal>.config</literal> file - - - The executable Spring.Services.WindowsService.Process.exe - is somewhat configured by the corresponding - .config 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. - - - For applications deployed in the standard way (i.e. on the filesystem - as explained above) the updating features are configured by the - watcher.xml file, if present, - as already seen. - - - 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. - - - For these scenarios, your deploy location will be something that - implements - Spring.Services.WindowsService.Common.Deploy.IDeployLocation. - - Please notice that, while questionable, it actually entends - IDisposable 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: - - -/// <summary> -/// Interface defining how a deploy location should look like -/// </summary> -public interface IDeployLocation : IDeployEventSource, IDisposable -{ - /// <summary> - /// The list of applications deployed at this location - /// Usually non-valid applications are not listed - /// </summary> - /// <seealso cref="Application"/> - IList Applications { get; } -} - -/// <summary> -/// Interface defining the contract for an object acting as the source of -/// deploy events (application added, removed, updated) -/// </summary> -/// <seealso cref="DeployEventArgs"/> -/// <seealso cref="DeployEventHandler"/> -public interface IDeployEventSource -{ - /// <summary> - /// The multicaster for deploy events - /// </summary> - event DeployEventHandler DeployEvent; -} - - - - + \ No newline at end of file diff --git a/doc/reference/src/xsd-configuration.xml b/doc/reference/src/xsd-configuration.xml index 4f3c7be0..498c6cce 100644 --- a/doc/reference/src/xsd-configuration.xml +++ b/doc/reference/src/xsd-configuration.xml @@ -8,7 +8,7 @@ This appendix details the use of XML Schema-based configuration in Spring. - The 'classic' + The 'classic' <object/>-based schema is good, but its generic-nature comes with a price in terms of configuration overhead. Creating a custom XML Schema-based configuration makes Spring XML @@ -58,7 +58,7 @@ you can copy and paste (!) and then plug <object/> definitions into like you have always done. However, the entire point of using custom schema tags is to make - configuration easier. + configuration easier. The rest of this chapter gives an overview of custom XML Schema @@ -90,10 +90,14 @@ <?xml version="1.0" encoding="UTF-8"?> <object xmlns="http://www.springframework.net" - xmlns:aop="http://www.springframework.org/schema/aop" - xmlns:tx="http://www.springframework.org/schema/tx"> + xmlns:aop="http://www.springframework.net/aop" + xmlns:tx="http://www.springframework.net/tx"> -<!-- <object/> definitions here --> + <!-- <object/> definitions here --> + + <!-- <tx/> transaction definitions here --> + + <!-- <aop/> AOP definitions here --> </object> @@ -106,6 +110,28 @@ the tags in the aop namespace are available to you. + + You will also need to configure the AOP and Transaction namespace + parsers in the main .NET application configuration file as shown + below + + <configuration> + + <configSections> + <sectionGroup name="spring"> + <!-- other Spring config sections handler like context, typeAliases, etc not shown for brevity --> + <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/> + </sectionGroup> + </configSections> + + <spring> + <parsers> + <parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop" /> + <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" /> + </parsers> + </spring> + +</configuration>
@@ -123,12 +149,33 @@ <?xml version="1.0" encoding="UTF-8"?> <objects xmlns="http://www.springframework.net" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:aop="http://www.springframework.org/schema/aop"> + xmlns:aop="http://www.springframework.net/aop"> -<!-- <object/> definitions here --> + <!-- <object/> definitions here --> + + <!-- <aop/> AOP definitions here --> </objects> + + You will also need to configure the AOP namespace parser in the + main .NET application configuration file as shown below + + <configuration> + + <configSections> + <sectionGroup name="spring"> + <!-- other Spring config sections handler like context, typeAliases, etc not shown for brevity --> + <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/> + </sectionGroup> + </configSections> + + <spring> + <parsers> + <parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop" /> + </parsers> + </spring> + +</configuration>
@@ -143,12 +190,33 @@ <?xml version="1.0" encoding="UTF-8"?> <objects xmlns="http://www.springframework.net" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:db="http://www.springframework.org/schema/db"> + xmlns:db="http://www.springframework.net/db"> -<!-- <object/> definitions here --> + <!-- <object/> definitions here --> + + <!-- <db/> database definitions here --> </objects> + + You will also need to configure the Database namespace parser in + the main .NET application configuration file as shown below + + <configuration> + + <configSections> + <sectionGroup name="spring"> + <!-- other Spring config sections handler like context, typeAliases, etc not shown for brevity --> + <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/> + </sectionGroup> + </configSections> + + <spring> + <parsers> + <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" /> + </parsers> + </spring> + +</configuration>
@@ -160,13 +228,34 @@ the chapter <?xml version="1.0" encoding="UTF-8"?> -<objects xmlns="http://www.springframework.org/schema/objects" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:r="http://www.springframework.org/schema/remoting"> +<objects xmlns="http://www.springframework.net" + xmlns:r="http://www.springframework.net/remoting"> -<!-- <object/> definitions here --> + <!-- <object/> definitions here --> + + <!-- <r/> remoting definitions here --> </objects> + + You will also need to configure the remoting namespace parser in + the main .NET application configuration file as shown below + + <configuration> + + <configSections> + <sectionGroup name="spring"> + <!-- other Spring config sections handler like context, typeAliases, etc not shown for brevity --> + <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/> + </sectionGroup> + </configSections> + + <spring> + <parsers> + <parser type="Spring.Remoting.Config.RemotingNamespaceParser, Spring.Services" /> + </parsers> + </spring> + +</configuration>
@@ -178,13 +267,34 @@ linkend="validation" /> <?xml version="1.0" encoding="UTF-8"?> -<objects xmlns="http://www.springframework.net" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:v="http://www.springframework.org/schema/validation"> +<objects xmlns="http://www.springframework.net" + xmlns:v="http://www.springframework.net/validation"> -<!-- <object/> definitions here --> + <!-- <object/> definitions here --> + + <!-- <v/> valdiation definitions here --> </objects> + + You will also need to configure the validation namespace parser in + the main .NET application configuration file as shown below + + <configuration> + + <configSections> + <sectionGroup name="spring"> + <!-- other Spring config sections handler like context, typeAliases, etc not shown for brevity --> + <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/> + </sectionGroup> + </configSections> + + <spring> + <parsers> + <parser type="Spring.Validation.Config.ValidationNamespaceParser, Spring.Core" /> + </parsers> + </spring> + +</configuration>
diff --git a/examples/Spring/Spring.Examples.Pool/Examples/Pool/Grep.cs b/examples/Spring/Spring.Examples.Pool/Examples/Pool/Grep.cs new file mode 100644 index 00000000..04f82015 --- /dev/null +++ b/examples/Spring/Spring.Examples.Pool/Examples/Pool/Grep.cs @@ -0,0 +1,140 @@ +//// +using System; +using System.IO; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Threading; +using Spring.Threading; + +namespace Spring.Examples.Pool +{ + public class Grep : IRunnable + { + private string file; + private string regexPattern; + + public class Match + { + string fileName, line; + int lineNum; + + public Match(string fileName, int lineNum, string line) + { + this.fileName = fileName; + this.lineNum = lineNum; + this.line = line; + } + + public void Print() + { + Console.Out.WriteLine("thread #{0}: {1}: {2}: {3}", Thread.CurrentThread.GetHashCode(), fileName, lineNum, line); + } + } + + public class Error + { + string file; + Exception e; + + public Error(string file, Exception e) + { + this.file = file; + this.e = e; + } + + public void Print() + { + Console.Out.WriteLine("file [{0}]: {1}", file, e.Message); + } + } + + public Grep(string file, string regexPattern) + { + this.file = file; + this.regexPattern = regexPattern; + } + + public void Run() + { + try + { + int lineNum = 1; + using (TextReader r = File.OpenText(file)) + { + string line = null; + while ((line = r.ReadLine()) != null) + { + if (Regex.IsMatch(line, Regex.Escape(regexPattern), RegexOptions.Singleline)) + { + new Grep.Match(file, lineNum, line).Print(); + } + lineNum++; + } + } + } + catch (Exception e) + { + new Grep.Error(file, e).Print(); + } + } + } + + public class ParallelGrep + { + //// + private PooledQueuedExecutor executor; + + public ParallelGrep(int size) + { + executor = new PooledQueuedExecutor(size); + } + + public void Recurse(string startPath, string filePattern, string regexPattern) + { + foreach (string file in Directory.GetFiles(startPath, filePattern)) + { + executor.Execute(new Grep(file, regexPattern)); + } + foreach (string directory in Directory.GetDirectories(startPath)) + { + Recurse(directory, filePattern, regexPattern); + } + } + + public void Stop() + { + executor.Stop(); + } + //// + + //// + public static void Main(string[] args) + { + if (args.Length < 3) + { + Console.Out.WriteLine("usage: {0} regex directory file-pattern [pool-size]", Assembly.GetEntryAssembly().CodeBase); + Environment.Exit(1); + } + + string regexPattern = args[0]; + string startPath = args[1]; + string filePattern = args[2]; + int size = 10; + try + { + size = Int32.Parse(args[3]); + } + catch + { + } + Console.Out.WriteLine ("pool size {0}", size); + + ParallelGrep grep = new ParallelGrep(size); + grep.Recurse(startPath, filePattern, regexPattern); + grep.Stop(); + } + //// + + } +} +//// diff --git a/examples/Spring/Spring.Examples.Pool/Examples/Pool/PooledQueuedExecutor.cs b/examples/Spring/Spring.Examples.Pool/Examples/Pool/PooledQueuedExecutor.cs new file mode 100644 index 00000000..60a959d8 --- /dev/null +++ b/examples/Spring/Spring.Examples.Pool/Examples/Pool/PooledQueuedExecutor.cs @@ -0,0 +1,190 @@ +//// +using System; +using System.Collections; +using System.Threading; +using Spring.Pool; +using Spring.Threading; + +namespace Spring.Examples.Pool +{ + /// + /// Factory of istances. + /// + //// + public class QueuedExecutorPoolableFactory : IPoolableObjectFactory + { + //// + //// + void IPoolableObjectFactory.DestroyObject(object o) + { + // ah, self documenting code: + // Here you can see that we decided to let the + // executor process all the currently queued tasks. + QueuedExecutor executor = o as QueuedExecutor; + executor.ShutdownAfterProcessingCurrentlyQueuedTasks(); + } + //// + + //// + bool IPoolableObjectFactory.ValidateObject(object o) + { + QueuedExecutor executor = o as QueuedExecutor; + return executor.Thread != null; + } + //// + + //// + void IPoolableObjectFactory.ActivateObject(object o) + { + QueuedExecutor executor = o as QueuedExecutor; + executor.Restart(); + } + //// + + //// + void IPoolableObjectFactory.PassivateObject(object o) + { + } + //// + + //// + object IPoolableObjectFactory.MakeObject() + { + // to actually make this work as a pooled executor + // use a bounded queue of capacity 1. + // If we don't do this one of the queued executors + // will accept all the queued IRunnables as, by default + // its queue is unbounded, and the PooledExecutor + // will happen to always run only one thread ... + return new QueuedExecutor(new BoundedBuffer(1)); + } + //// + } + + //// + public class PooledObjectHolder : IDisposable + { + IObjectPool pool; + object pooled; + + /// + /// Builds a new + /// trying to borrow an object form it + /// + /// + private PooledObjectHolder(IObjectPool pool) + { + this.pool = pool; + this.pooled = pool.BorrowObject(); + } + + /// + /// Allow to access the borrowed pooled object + /// + public object Pooled + { + get + { + return pooled; + } + } + + /// + /// Returns the borrowed object to the pool + /// + public void Dispose() + { + pool.ReturnObject(pooled); + } + + /// + /// Creates a new for the + /// given pool. + /// + public static PooledObjectHolder UseFrom(IObjectPool pool) + { + return new PooledObjectHolder(pool); + } + } + //// + + public class PooledQueuedExecutor : IExecutor + { + Spring.Pool.SimplePool pool; + private IList syncs; + + class Queuer + { + IObjectPool pool; + IRunnable runnable; + private ISync sync; + + public Queuer (IObjectPool pool, IRunnable runnable) + { + this.pool = pool; + this.runnable = runnable; + this.sync = new Latch(); + } + + public void Queue () + { + //// + using (PooledObjectHolder holder = PooledObjectHolder.UseFrom(pool)) + { + QueuedExecutor executor = (QueuedExecutor) holder.Pooled; + executor.Execute(runnable); + } + //// + sync.Release(); + } + + public static ISync Queue (IObjectPool pool, IRunnable runnable) + { + Queuer queuer = new Queuer(pool, runnable); + Thread thread = new Thread(new ThreadStart(queuer.Queue)); + thread.Start(); + return queuer.Sync; + } + + public ISync Sync + { + get + { + return sync; + } + } + } + + public PooledQueuedExecutor(int size) + { + //// + pool = new SimplePool(new QueuedExecutorPoolableFactory(), size); + //// + syncs = ArrayList.Synchronized(new ArrayList()); + } + + public PooledQueuedExecutor() + : this(10) + { + } + + public void Execute(IRunnable runnable) + { + // queue the task and remember its ISync ... + syncs.Add(Queuer.Queue(pool, runnable)); + } + + //// + public void Stop () + { + // waits for all the grep-task to have been queued ... + foreach (ISync sync in syncs) + { + sync.Acquire(); + } + pool.Close(); + } + //// + } +} +//// \ No newline at end of file diff --git a/examples/Spring/Spring.Examples.Pool/Spring.Examples.Pool.csproj b/examples/Spring/Spring.Examples.Pool/Spring.Examples.Pool.csproj new file mode 100644 index 00000000..c4f5265a --- /dev/null +++ b/examples/Spring/Spring.Examples.Pool/Spring.Examples.Pool.csproj @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Spring/Spring.Examples.Pool/Spring.Examples.Pool.sln b/examples/Spring/Spring.Examples.Pool/Spring.Examples.Pool.sln new file mode 100644 index 00000000..2e07bb35 --- /dev/null +++ b/examples/Spring/Spring.Examples.Pool/Spring.Examples.Pool.sln @@ -0,0 +1,29 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core", "..\..\..\src\Spring\Spring.Core\Spring.Core.2003.csproj", "{710961A3-0DF4-49E4-A26E-F5B9C044AC84}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Examples.Pool", "Spring.Examples.Pool.csproj", "{C261D9ED-85C3-4B35-BE48-7156F5B17430}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug.ActiveCfg = Debug|.NET + {710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug.Build.0 = Debug|.NET + {710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release.ActiveCfg = Release|.NET + {710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release.Build.0 = Release|.NET + {C261D9ED-85C3-4B35-BE48-7156F5B17430}.Debug.ActiveCfg = Debug|.NET + {C261D9ED-85C3-4B35-BE48-7156F5B17430}.Debug.Build.0 = Debug|.NET + {C261D9ED-85C3-4B35-BE48-7156F5B17430}.Release.ActiveCfg = Release|.NET + {C261D9ED-85C3-4B35-BE48-7156F5B17430}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/lib/Net/2.0/Apache.NMS.MSMQ.dll b/lib/Net/2.0/Apache.NMS.MSMQ.dll index 2620faf1..19082fe7 100644 Binary files a/lib/Net/2.0/Apache.NMS.MSMQ.dll and b/lib/Net/2.0/Apache.NMS.MSMQ.dll differ diff --git a/lib/Net/2.0/Apache.NMS.dll b/lib/Net/2.0/Apache.NMS.dll index efe6be21..b2369c8f 100644 Binary files a/lib/Net/2.0/Apache.NMS.dll and b/lib/Net/2.0/Apache.NMS.dll differ diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Spring.Data.NHibernate.Integration.Tests.2003.csproj b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Spring.Data.NHibernate.Integration.Tests.2003.csproj index 175e4527..a3823a90 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Spring.Data.NHibernate.Integration.Tests.2003.csproj +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Spring.Data.NHibernate.Integration.Tests.2003.csproj @@ -79,16 +79,6 @@ AssemblyName = "System.Xml" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" /> - - + + + + +