View Full Version : Confusion re configuring injection and ASMX handler
pmcevoy
01-18-2006, 04:52 PM
Gents,
I must be dumb, but I'm having difficulty getting dependancy injection working for web services. I've followed the examples in the doc, but my webservice class is still getting instantiated by .Net, rather than the WebServiceExporter (which I believe I should be using).
I have the following Web.Config:
<objects>
<object id="Service.asmx" type="IMSUniversal.Adapters.Common.OutputOnlyService, IMSUniversal.Adapters.Common" abstract="true" />
<object id="ListenerServiceExporter" type="Spring.Web.Services.WebServiceExporter, Spring.Web" abstract="true">
<property name="TargetName" value="ListenerService"/>
</object>
<object id="ListenerService" type="IMSUniversal.Adapters.Common.OutputOnlyService, IMSUniversal.Adapters.Common">
<property name="ServiceImpl" ref="ListenerServiceImpl"/>
</object>
<object id="ListenerServiceImpl" type="IMSUniversal.Adapters.Common.OutputOnlyStub, IMSUniversal.Adapters.Common" />
</objects>
The HttpHandler is working fine, and is passing the request to Service.asmx to the correct class, however I am finding that when I invoke the service, that the ServiceImpl property of the ListenerService is set to null.
I'm certain it's a configuration thing as I can't figure out why the OutputOnlyService type is referenced twice (once by Service.asmx, and once by ListenerService), but this seems to be how the docs explain how to set it up. Can anyone check the semantics of my spring section above?
It's just not altogether clear from the docs, how the HttpHandler and the WebExporter are supposed to play together.
I'm using .Net 2.0 (within VS2005) with the latest nightly (17-jan-2006)
Cheers
Pete
Aleks Seovic
01-19-2006, 04:44 AM
Hi Pete,
I see two problems with your configuration.
First of all, you should not define Service.asmx in your config file. That definitions will be created and registered by the WebServiceExporter. Second, in order for the WebServiceExporter to work it should not be declared as abstract.
Here is the simplest possible example of how to export a web service:
<object id="CalculatorService" type="TestServices.Calculator, TestServices"/>
<object id="CalculatorWS" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="CalculatorService"/>
<property name="Name" value="Calculator"/>
<property name="Namespace" value="http://SpringWS/WebServices"/>
<property name="Description" value="My calculator web service"/>
</object>
Name property determines the URL of the web service, so in this case, because Name property is set to Calculator, you would access the exported service using Calculator.asmx as a service URL.
Namespace and Description properties are not strictly required, but I do recommend that you set them for each service. Description is the easiest way to check if you really are hitting the service exported by Spring.NET by simply typing service URL in the browser.
In the example above nothing is injected into the CalculatorService instance, but all it would take to inject values into it is to define appropriate property elements within its definition.
Try changing your config file to match example above and you should be ok.
HTH,
Aleks
P.S. We will change WebServiceExporter to serve as an object factory as well in the near future, which will make Name property redundant as exporter's object id will serve the same purpose. Until then, however, you should use Name property to define how your service should be called.
pmcevoy
01-19-2006, 09:34 AM
Aleks,
Thanks for your quick reply.... I had tried all manner of combinations, and had actually tried something almost the same as what you suggest, but what nailed me was marking the WebServiceExporter as abstract. Once that was removed, it works a treat. I've no idea why I marked it as abstract - the docs are quite clear - I have a feeling it was from another out of date post within the forum.
To close the loop for others with this problem, my Spring configuration within my web.config looks like:
<objects>
<object id="ListenerServiceExporter" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="ListenerService"/>
<property name="Name" value="Service"/>
<property name="Namespace" value="http://www.industria.com/Service"/>
<property name="Description" value="Service"/>
</object>
<object id="ListenerService" type="IMSUniversal.Adapters.Common.OutputOnlyService, IMSUniversal.Adapters.Common">
<property name="ServiceImpl" ref="ListenerServiceImpl"/>
</object>
<object id="ListenerServiceImpl" type="IMSUniversal.Adapters.Common.OutputOnlyStub, IMSUniversal.Adapters.Common" />
</objects>
I do need to mention, though, that contrary to what you say, I must specify the Namespace property, otherwise I get NullReferenceException.
One final point about Namespace and Description. I am using the WebExporter to wrap a regular .Net webservice class that inherits from serverInterfaces file generated by wsdl.exe. This webservice class has a WebService attribute with a Namespace for the service already declared in it. Is it possible to get the WebServiceExporter to use _that_ namespace as it's default?
Pete
Aleks Seovic
01-19-2006, 04:49 PM
You are right, Mark made the Namespace optional for a while, but I believe my latest changes made it required again.
You also bring up a good point -- we are looking at WebMethod attributes if they exist and copying all the values to the proxy class, so we should probably do the same for the WebService attribute at the class level.
Will do,
Aleks
Aleks Seovic
01-20-2006, 10:51 AM
Done.
I updated WebServiceExporter to use existing WebServiceAttribute if possible, so you should be able to do something like this:
<object id="ListenerService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="ListenerServiceTarget"/>
</object>
I also changed web service URL resolution algorithm a bit, so you need to access it using <exporterId>.asmx instead of <Name>.asmx. In the example above, you would access ListenerService.asmx. This is more consistent with the access to other types of exported services and to Spring-managed .aspx pages.
Name property also defaults to exporter object ID now, so you don't really need to specify it.
Later,
Aleks
pmcevoy
01-20-2006, 12:02 PM
Aleks,
This is a fantastic turn-around on this fix! TBH, I think you are correct to change the URL resolution to use the exporter id - it seems more intuitive to me too.
Will you be updating the docs too? This is a bit of a change and I think this thread has cleared up a lot with regard to webservice injection.
I'll try this on monday, once the nightly build gets updated.
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.