PDA

View Full Version : DI with Spring.NET and WCF


greenguy
06-11-2007, 02:03 PM
Hello,
My site will be using Spring.NET for DI, localization and validation. Our ASP.NET 2.0 web client will be consuming WCF services using a net-tcp endpoint. In my prototype web app, I am using the following code to register the service with Spring:


<!--service definition-->
<object id="postingSearchService" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
<property name="ProxyType" value="SpringSearch.PostingSearchService.SearchServiceCli ent, SpringSearch" />
<property name="ServiceInterface" value="SpringSearch.PostingSearchService.ISearchService, SpringSearch"/>
</object>



<!--page definition-->
<object type="search-jobs.aspx" parent="jobSeekerPage">
<property name="PostingSearchService" ref="postingSearchService" />
</object>


SearchServiceClient is of Type System.ServiceModel.ClientBase<ISearchService> and implements the ISearchService interface which is the service contract available to me on the web client.


When I run the app and trace the calls made to the service (using Microsoft's service trace viewer), I see a "Construct ChannelFactory" activity on each page load and a "Open ClientBase" activity on each call to the service. However, I never see a "Close ClientBase" activity, even after the application is shut down. I can't explicitly call the close method on the serviceclient instance since the ISearchService interface does not contain that method definition. I want to close the channel as soon as possible for resource management purposes.


Questions about this:
1. What are the best practices with Spring.NET as it pertains to DI with WCF services? I am concerned that the application is opening channels but not closing them.

2. Our site gets over 1 million page views a day. Will this approach of injecting the service instances at run time scale appropriately?

thanks in advance for any help.

Bruno Baia
06-11-2007, 02:57 PM
Hi,

You are trying to use a .NET 2.0 feature for .NET 3.0, WebServiceProxyFactory can work with WCF if your service is using basic http binding, otherwise this is not appropriate.
Anyway, this works and the problem you are talking about is not related to Spring but to WCF:
The ClientBase class implements IDisposable, and guess what is doing the Dispose method ? it calls the Close method.
The proxy generated by WebServiceProxyFactory inherits from your ProxyType so you should be able to cast it as a IDisposable instance.


Another point is why are you using WebServiceProxyFactory here ? Why not directly use the proxy type ? The proxy type already implements your service interface !

<object id="postingSearchService" type="SpringSearch.PostingSearchService.SearchServiceCli ent, SpringSearch" />



Another solution, if you don't want to generate the proxy type, is to let WCF generate it dynamically, here an example :

<!-- returns ChannelFactory<ICalculator>("calculatorEndpoint").CreateChannel() -->
<object id="webCalculator"
type="Spring.WcfQuickStart.ICalculator, Spring.WcfQuickStart.ClientApp"
factory-object="webCalculatorChannelFactory"
factory-method="CreateChannel" />
<object id="webCalculatorChannelFactory"
type="System.ServiceModel.ChannelFactory&lt;Spring.WcfQuick Start.ICalculator>, System.ServiceModel">
<constructor-arg name="endpointConfigurationName" value="webCalculatorEndpoint" />
</object>


There is a WCF integration within CVS, download one of the latest nightly build (http://www.springframework.net/downloads/nightly/) and take a look to the WcfQuickStart example.


HTH,
Bruno

mcarson
10-23-2008, 12:12 AM
Hello,
I am a Spring.NET newbie who is having trouble trying to host a WCF service in IIS and still use Spring's DI for the service object. Whenever my client app calls the service, I'm getting this error:
"There must exist exactly one object definition of type 'MyNameSpace.MyService' in the Spring container."

According to the 1.2 M1 documentation this can happen if I have more than one object of the same type in my config file. In my case, the only <object> in my config file is:
<object id="myServiceObj" type="MyNameSpace.MyService, Bin" singleton="false">
<property name="myProperty1" value="2"/>
</object>
and my svc looks like this:
<%@ServiceHost language="c#" Debug="true" Service="MyNameSpace.MyService" Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>

and I have only exposed one endpoint for the service:
<service name="MyNameSpace.MyService" behaviorConfiguration="myServiceBehavior">
<endpoint address="" contract="MyNameSpace.IMyService" binding="basicHttpBinding" bindingConfiguration="myHttpEndpointBinding"/>
<endpoint address="mex" binding="basicHttpBinding" bindingConfiguration="myHttpEndpointBinding" contract="IMetadataExchange"/>
</service>

I mimicked how the CalculatorService is hosted in IIS in the WcfQuickStart solution. The only difference I can see is that I have included my service as a DLL in the host project's "Bin" rather than adding the code in "App_code". Any advice would be greatly appreciated.

Also, I noticed that the section 28.2.2(from the M1) documentation is not found in the 1.2 RC1 documentation. Is there a reason for this?

mcarson
10-27-2008, 03:26 PM
Never mind. I have found a solution. I was including the wrong assembly, and some of the DI internal to the class that I was hosting was not working correctly with the service factory.

However, I am still concerned that 28.2.2 has been removed from the 1.2.0 RC1 documentation. Is this functionality not going to be there when the final release comes out?!