![]() |
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). For those who would like to get their feet wet right way, check out the WcfQuickStart application in the examples directory. The technical approach used to perform dependency injection is based on dynamically creating 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.
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, 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>
To host this service type in a standalone application define an
instance of a
<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>
Outside of a standalone application you can also use the class
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. You can also use
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
<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. To create a client side proxy based on the use of ChannelFactory<T>, you can use Spring's WCF schema to create an instance of the interface that will communicate over a WCF channel. See section on the Spring WCF Schema for more information. <objects xmlns="http://www.springframework.net" xmlns:wcf="http://www.springframework.net/wcf"> <!-- returns ChannelFactory<ICalculator>("calculatorEndpoint").CreateChannel() --> <wcf:channelFactory id="serverAppCalculator" channelType="Spring.WcfQuickStart.ICalculator, Spring.WcfQuickStart.Contracts" endpointConfigurationName="serverAppCalculatorEndpoint" /> </objects> The value 'serverAppCalculatorEndpoint' refers to the name of an enpoints in the <client> section of the standard WCF configuration inside of App.config. Much like the approach taken for .asmx web services Spring provides
an exporter that will add <object id="HelloWorldExporter" type="Spring.ServiceModel.ServiceExporter, Spring.Services"> <property name="TargetName" value="HelloWorld"/> <property name="MemberAttributes"> <dictionary> <entry key="SayHelloWorld"> <object type="System.ServiceModel.OperationContractAttribute, System.ServiceModel"> <property name="IsOneWay" value="false"/> <!-- configure any other OperationContractAttribute properties here --> </object> </entry> </dictionary> </property> </object> Spring does not provide any means to add
|