diff --git a/doc/reference/src/index.xml b/doc/reference/src/index.xml
index 00c86dcd..40cc3a46 100644
--- a/doc/reference/src/index.xml
+++ b/doc/reference/src/index.xml
@@ -23,6 +23,7 @@
+
@@ -285,12 +286,16 @@
+
+
+
&psa-intro;
&remoting;
&services;
&webservices;
+ &wcf;
diff --git a/doc/reference/src/messaging.xml b/doc/reference/src/messaging.xml
index 2661b1b1..d810bc6a 100644
--- a/doc/reference/src/messaging.xml
+++ b/doc/reference/src/messaging.xml
@@ -44,13 +44,14 @@
SonicMQ in namespace Spring.Messaging.Sonic,
- 'Jms' is sometimes used as the class prefix.
+ 'Jms' is sometimes used as the class prefix. (available 1.2
+ RC1)
Websphere MQ in namespace
Spring.Messaging.Xms, 'Xms' is sometimes used as
- the class prefix
+ the class prefix (available 1.2 RC1)
@@ -1270,17 +1271,19 @@ namespace MyApp
recovery-interval
- The time interval between connection recovery attempts. The default is 5 seconds.
- Specify as a TimeSpan value using Spring's TimeSpanConverter (e.g. 10s, 10m, 3h, etc)
-
+ The time interval between connection recovery
+ attempts. The default is 5 seconds. Specify as a TimeSpan value
+ using Spring's TimeSpanConverter (e.g. 10s, 10m, 3h, etc)
+ max-recovery-time
- The maximum time try reconnection attempts. The default is 10 minutes. Specify as a
- TimeSpan value using Spring's TimeSpanConverter (e.g. 10s, 10m, 3h, etc)
-
+ The maximum time try reconnection attempts. The
+ default is 10 minutes. Specify as a TimeSpan value using
+ Spring's TimeSpanConverter (e.g. 10s, 10m, 3h, etc)
+
@@ -1300,7 +1303,7 @@ namespace MyApp
implementation. The most important resource to cache is the JMS Connection
since the flow of events in the message template class (EmsTemplate) is to
create/close a connection on each operation and this is an expensive
- operation.
+ operation.
Spring provides a convenience class, SingleConnectionFactory, in
which the same Connection is returned on calls to CreateConnection() and
diff --git a/doc/reference/src/wcf.xml b/doc/reference/src/wcf.xml
new file mode 100644
index 00000000..e067ac72
--- /dev/null
+++ b/doc/reference/src/wcf.xml
@@ -0,0 +1,286 @@
+
+
+ Windows Communication Foundation (WCF)
+
+
+ Introduction
+
+ Spring's WCF support allows you to configure your WCF services via
+ dependency injection and add additional behavior to them using
+ Aspect-Oriented programming (AOP).
+
+ There are two approaches in the 1.2 M1 release for configuring your
+ services with DI which are discussed in the following sections. One
+ approach creates an implementation of your service interface (a dynamic
+ proxy) that retrieves a configured instance of your service type from the
+ Spring container. This dynamic proxy is then the final service type that
+ is hosted. The second approach uses the extension points in WCF itself to
+ delegate to the Spring container to create and configure your service
+ type. Both approaches are discussed below.
+
+ As it is desirable to have just one approach, we would greatly
+ appreciate your input regarding these two approaches as well as any other
+ suggestions regarding WCF support.
+
+ For those who would like to get their feet wet right way, check out
+ the WcfQuickStart application in the examples directory.
+
+
+
+ Configuring WCF services via Dependency Injection
+
+ In this approach the container will creates an implementation of
+ your service interface (a dynamic proxy) that retrieves a configured
+ instance of your service type from the Spring container. This dynamic
+ proxy is then the final service type that is hosted.
+
+
+ Dependency Injection using dynamic proxies
+
+ In this approach you develop your WCF services as you would
+ normally do. For example here is a sample service type taken from the
+ quickstart example.
+
+ [ServiceContract(Namespace = "http://Spring.WcfQuickStart")]
+ public interface ICalculator
+ {
+ [OperationContract]
+ double Add(double n1, double n2);
+ [OperationContract]
+ double Subtract(double n1, double n2);
+ [OperationContract]
+ double Multiply(double n1, double n2);
+ [OperationContract]
+ double Divide(double n1, double n2);
+ [OperationContract]
+ string GetName();
+ }
+
+ The implementation for the methods is fairly obvious but an
+ additional property, SleepInSeconds, is present. This
+ is the property we will configure via dependency injection. Here is a
+ partial listing of the implementation
+
+ public class CalculatorService : ICalculator
+ {
+ private int sleepInSeconds;
+
+ public int SleepInSeconds
+ {
+ get { return sleepInSeconds; }
+ set { sleepInSeconds = value; }
+ }
+
+ public double Add(double n1, double n2)
+ {
+ Thread.Sleep(sleepInSeconds*1000);
+ return n1 + n2;
+
+ }
+
+
+ // additional implementation not shown for brevity
+
+ }
+
+ To configure this object with Spring, provide the XML
+ configuration metadata as shown below as you would with any Spring
+ managed object.
+
+ <object id="calculator" singleton="false" type="Spring.WcfQuickStart.CalculatorService, Spring.WcfQuickStart.ServerApp">
+ <property name="SleepInSeconds" value="1"/>
+ </object>
+
+
+
+ The object must be declared as a 'prototype' object, i.e. not a
+ singleton, in order to interact correctly with WCF instancing.
+
+
+ To host this service type in a standalone application define an
+ instance of a
+ Spring.ServiceModel.Activation.ServiceHostFactoryObject
+ and set is property TargetName to the id value of
+ the previously defined service type.
+ ServiceHostFactoryObject is a Spring
+ IFactoryObject implementation. (See here for more
+ information on IFactoryObjects and their
+ interaction with the container.) The
+ ServiceHostFactoryObject will create an instance
+ of
+ Spring.ServiceModel.Activation.SpringServiceHost
+ that will be the ServiceHost instance associated with your service type.
+ This configuration for this step is shown below.
+
+ <object id="calculatorServiceHost" type="Spring.ServiceModel.Activation.ServiceHostFactoryObject, Spring.Services">
+ <property name="TargetName" value="calculator" />
+ </object>
+
+ Additional service configuration can be done declaratively in the
+ standard App.config file as shown below
+
+ <system.serviceModel>
+ <services>
+ <service name="calculator" behaviorConfiguration="DefaultBehavior">
+ <host> ... </host>
+ <endpoint> ... </endpoint>
+ </service>
+ ...
+ </services>
+
+</system.serviceModel>
+
+
+ It is important that the name of the service in the WCF
+ declarative configuration section match the name of the Spring object
+ definition
+
+
+ Spring.ServiceModel.Activation.SpringServiceHost
+ is where the dynamic proxy for your service type is
+ generated. This dynamic proxy will implement a single 'WCF' interface,
+ the same on that your service type implements. The implementation of the
+ service interface methods on the proxy will delegate to a wrapped
+ 'target' object which is the object instance retrieved by name from the
+ Spring container using the Spring API,
+ ApplicationContext.GetObject(name). Since the
+ object retrieved in this manner is fully configured, your WCF service is
+ as well.
+
+ Outside of a standalone application you can also use the class
+ Spring.ServiceModel.Activation.ServiceHostFactory
+ (which inherits from
+ System.ServiceModel.Activation.ServiceHostFactory)
+ to host your services so that they can be configured via dependency
+ injection. To use the dynamic proxy approached described here you should
+ still refer to the name of the service as the name of the object
+ definition used to configure the service type in the Spring
+ container.
+
+ There are not many disadvantages to this approach other than the
+ need to specify the service name as the name of the object definition in
+ the Spring container and to ensure that singleton=false is used in the
+ object definition.
+
+
+
+ Dependency Injection using WCF extensibility points.
+
+ The second approach uses the extensibility points in WCF itself to
+ delegate to Spring to create and configure your WCF service. This
+ approach was first taken (afaik) by Oran Dennison on his blog
+ and several other folks on the web since then. In this approach Spring
+ specific implementations of the WCF interfaces
+ System.ServiceModel.Dispatcher.IInstanceProvider
+ and
+ System.ServiceModel.Description.IServiceBehavior
+ are used to integrate Spring directly into the instancing of WCF
+ services.
+
+ Spring's implementation of
+ IInstanceProvider is
+ Spring.ServiceModel.Dispatcher.SpringInstanceProvider.
+ This implementation will look for an object by type in the Spring
+ container and retrieve an instance configured using DI. If there is more
+ than one object of the type registered with the container than an
+ exception will be thrown. The
+ SpringInstanceProvider is used by a custom
+ service behavior class,
+ Spring.ServiceModel.Dispatcher.SpringServiceBehavior
+ where it is applied to all the service endpoints. This behavior is then
+ added to the custom service host
+ Spring.ServiceModel.Activation.SpringServiceHost
+
+ The service type is used to locate the object in the container. In
+ your .svc file you specify the custom service host type and also the
+ type of the service. Here is an example taken from the WcfQuickStart
+ application that shows the use of this approach inside IIS.
+
+ <%@ ServiceHost Language="C#" Debug="true" Service="Spring.WcfQuickStart.CalculatorService"
+ Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>
+
+
+ The Spring configuration for the object is shown below.
+
+ <object id="calculator" type="Spring.WcfQuickStart.CalculatorService, App_Code" singleton="false">
+ <property name="SleepInSeconds" value="1"/>
+ </object>
+
+
+ The object must be declared as a 'prototype' object, i.e. not a
+ singleton, in order to interact correctly with WCF instancing.
+
+
+ While integrating 'natively' with WCF does seem to be the most
+ natural approach there is one 'gotya' that needs to be investigated
+ further to see if there is an acceptable workaround in order for this
+ approach to be viable. The issue is that if the service is configured to
+ be a singleton, for example using
+ [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
+ then the invocation of the IInstanceProvider is
+ short-circuited. See the notes on the MSDN class documentation here.
+ One workaround, which is not very appealing, is to use the PerCall
+ instancing mode but set the singleton attribute in the Spring
+ configuration to true, this way the same instance is always
+ returned.
+
+
+
+
+ Apply AOP advice to WCF services
+
+ In either approach to performing dependency injection you can apply
+ additional AOP advice to your WCF services in the same way as you have
+ always done in Spring. The following configuration shows how to apply some
+ simple performance monitoring advice to all services in the
+ Spring.WcfQuickStart namespace and is taken from
+ the QuickStart example.
+
+ <object id="serviceOperation" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
+ <property name="pattern" value="Spring.WcfQuickStart.*"/>
+ </object>
+
+ <object id="perfAdvice" type="Spring.WcfQuickStart.SimplePerformanceInterceptor, Spring.WcfQuickStart.ServerApp">
+ <property name="Prefix" value="Service Layer Performance"/>
+ </object>
+
+ <aop:config>
+ <aop:advisor pointcut-ref="serviceOperation" advice-ref="perfAdvice"/>
+ </aop:config>
+
+ The aop:config section implicitly uses Spring's autoproxying
+ features to add additional behavior to any objects defined in the
+ container that match the pointcut criteria.
+
+
+
+ Creating client side proxies declaratively
+
+ To create a client side proxy based on the use of
+ ChannelFactory<T>, you can use this rather ugly 'boiler plate' XML
+ snippit that takes uses Spring's support for calling factory methods on
+ object instances.
+
+ <!-- returns ChannelFactory<ICalculator>("calculatorEndpoint").CreateChannel() -->
+
+ <object id="serverAppCalculator" type="Spring.WcfQuickStart.ICalculator, Spring.WcfQuickStart.ClientApp"
+ factory-object="serverAppCalculatorChannelFactory"
+ factory-method="CreateChannel" />
+
+ <object id="serverAppCalculatorChannelFactory"
+ type="System.ServiceModel.ChannelFactory<Spring.WcfQuickStart.ICalculator>, System.ServiceModel">
+
+ <constructor-arg name="endpointConfigurationName" value="serverAppCalculatorEndpoint" />
+
+ </object>
+
+
+ This will be shortened using a custom namespce in the 1.2 RC1
+ release
+
+
+
\ No newline at end of file