Building webservices with Spring.Net

Building and consuming anything but a trivial web service with Visual Studio can be quite an error prone task. The service itself is difficult to test outside of the web environment, the proxy class generated by Visual Studio will, most of the time, be in a conflicted state in your code repository as multiple developers add and change methods. It’s also quite cumbersome if you want to map those proxy classes back to your own classes. The list goes on and while Windows Communication Foundation does solve some of these issues I’d like to introduce you to the service infrastructure of Spring.Net which can help you to expose your services and is available on .net 2.0.

Let’s first look at the server side. Instead of decorating your service with webservice and webmethod attributes you can write a plain old c# object (poco) which can be tested like any other class and be hosted in multiple environments, exposing the service via remoting is just a configuration change. Nothing even prevents you from making a fat client, just keep the service itself behind an interface.

public class ProductService
: IProductService
{
	private List<ProductDto> products;
 
	public ProductService()
	{
		products = new List<ProductDto>();
		products.Add(new ProductDto("Pizza Margherita",9.75));
		products.Add(new ProductDto("Pizza Pepperoni Lovers",10.95));
		products.Add(new ProductDto("Pizza Cheesam ",10.95));
	}
 
	#region IProductService Members
 
	public RetrieveProductsResponse RetrieveProducts(RetrieveProductsRequest request)
	{
		return new RetrieveProductsResponse(products);
	}
 
	public SearchProductsResponse SearchProducts(SearchProductsRequest request)
	{
		List<ProductDto> productMatches = new List<ProductDto>();
		foreach (ProductDto product in products)
		{
			if (product.Name.ToUpper().Contains(request.Name.ToUpper()))
			{
				productMatches.Add(product);
			}
		}
		return new SearchProductsResponse(productMatches);
	}
 
	#endregion
}

As you can see, nothing fancy here. The ProductDto, requests, responses and the service interface are all located in an assembly which will be shared between the client and the server.

Whenever you build a service layer around your application, the best way to look upon it is like a GUI. You expose the behaviour of your domain, just not with web or winforms.

Since the service is just a poco, putting it into your spring configuration is just like you would add any other class. You can perform DI, AOP, … upon it like you’d normally do.

<object name="ProductService" type="Service.ProductService, Service"/>

To make it available as a webservice you use the Webservice exporter which can be found in the Spring.Web assembly as illustrated below.

<object id="ProductWebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
  <property name="TargetName" value="ProductService"/>
  <property name="Namespace" value="http://www.bennymichielsen.be/services"/>
  <property name="Description" value="Defines operations upon products"/>
  <property name="MemberAttributes">
    <dictionary>
      <entry key="RetrieveProducts">
        <object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
          <property name="Description" value="Retrieves all products"/>
          <property name="MessageName" value="RetrieveProducts"/>
        </object>
      </entry>
      <entry key="SearchProducts">
        <object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
          <property name="Description" value="Searches for products which have a name like the one supplied."/>
          <property name="MessageName" value="SearchProducts"/>
        </object>
      </entry>
    </dictionary>
  </property>
</object>

Using the Webservice exporter you can export any object in your configuration as a webservice, just point it to the appropriate object definition using the TargetName property. I’ve populated some more properties just to show how you can use this class. It is however necessary to have an interface(s) on your service, but since this is a best practice anyhow I don’t see this as a shortcoming.

On the client side a similar approach can be used to consume the webservice using the WebserviceProxy factory in the Spring.Services assembly. Using this class your code can depend upon the service interface instead of the proxy class itself. If you want to use the proxy class, this is still supported. In this case Spring will create a proxy which will implement the service interface and map to the Visual Studio proxy. Note that the original service does not have to implement this interface, the methods supplied in the interface are mapped using a kind of duck typing. This is very useful if you don’t control the service but are consuming it and don’t want to tightly couple your code.

If you do control both sides, it is much easier to let the proxy be generated at runtime.

<object name="ProductService" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
  <property name="ServiceUri" value="http://localhost:1871/ProductWebService.asmx"/>
  <property name="ServiceInterface" value="ServiceContract.Interface.IProductService, ServiceContract"/>
</object>

This allows you to use the service interface, the concrete implementation is of no concern. What’s also very useful is that you can reuse all the classes which are already in the service contract assembly, thus preventing your solution from being polluted with any additional code.

For more information please take a look at the documentation.

SpringWebservicesSample.zip (1.22 mb)

Blogging tools

Since there’s no code highlighter that works for me in Blogengine.Net I use this site. It pretty much supports any language, paste your code, select some options and you get your html to use.

To check my spelling I use this site, I’ve been using it for years now. Though I don’t need it when I’m using my Mac since it checks everything you write, regardless the application you are using.

Initializing an array with arrayWithObjects

If you’re creating an array and adding objects to it at initialization, in Cocoa, don’t forget that the last element of the list needs to be nil, it’ll save you debugging time ;).

NSMutableArray *array = [NSMutableArray arrayWithObjects: @"one", @"two", @"three", @"four", nil];

Developer reference.

Cocoa Programming for Mac OS X (Ch 19-21)

After a little Cocoa break I’m back, while continuing through the book I seemed to have forgotten some stuff already, not good.

So, next up, Keyboard Events.

This chapter explains how the events are used for handling keystrokes as well as the first responder concept. The first responder being the active view element (button, text area,…) and there’s a whole mechanism working in the background when the first responder changes. Not a lot of ground breaking material here, probably the most important piece of code here is an example of how to code the fuzzy blue box around an active custom view.

Chapter 20, Drawing text with attributes.

Here we are taught how to show strings in various formats, not that interesting. One nice feature however is that all the drawing commands you write can be converted into PDF by the AppKit framework.

Chapter 21, Pasteboards and Nil-Targeted actions.

The clipboard in Windows, pasteboard in OS X. Different name, same concept, although I’ve never read about it in any .Net book I’ve seen but you know what it does :). What you need to remember from this chapter is that you can do a lazy paste. Meaning that you don’t have to put it in the clip errr pasteboard when the user presses the copy command. You can wait until he presses paste, very valuable if you’re working with large quantities of data.

Nil targeted actions are best explained with an example. You can set the selector (method signature for .net people) of a menu item to anything you want, say removeEmployee:, when the menu item’s target is nil and the menu item is invoked, it will traverse the responder tree until someone acts upon it.

Nothing fancy was covered in these past chapters, but you need to know about these things. I did spend quite some time on the applications, probably because there was a two week pause. For those interested I’ve attached all the source code.

As always, you can get the book here .

TypingTutor – Chapter 19.zip (46.44 kb)

TypingTutor – Chapter 20.zip (53.47 kb)

TypingTutor – Chapter 20 Challenge 1.zip (53.73 kb)

TypingTutor – Chapter 20 Challenge 2.zip (57.89 kb)

TypingTutor – Chapter 21.zip (53.58 kb)

TypingTutor – Chapter 21 Challenge 1.zip (53.75 kb)

RaiseMan – Chapter 21 Challenge 2.zip (111.20 kb)

Developing .NET Software on a Mac

Followed some links and found this podcast on deep fried bytes. It’s interesting to hear, although the title is a bit misleading. They talk about .net development 25% of the time using virualization tools like VM Ware, the rest of the podcast is filled with general switchers info and some recommended applications.

Nothing about Mono though, too bad.

Adding object definitions from non-local classes

On the Spring forum someone asked if it was possible to add object definitions to the application context of classes which were beyond the searchable range of the application. I was a little bit sceptic at first but one debugging session later, I found out that it is possible to do this. Though I really don't support the whole idea of doing this.

When you are not using fully qualified assembly names in your definition Spring will look at the current loaded assemblies to resolve the type, so with this trick you can make it work. The topic can be found here and the source code can be found here, don't forget to change the path of the “ClassLibrary1” assembly to make it work.

class Program
{
	static void Main(string[] args)
	{
		Assembly.LoadFile(@"C:MyPathToSomeDllClassLibrary1.dll");
		object o = ContextRegistry.GetContext().GetObject("MyObject");
		Console.WriteLine("Retrieved object from context");
		Console.ReadLine();
	}
}

<objects xmlns="http://www.springframework.net" >
  <object id="MyObject"
          type="ClassLibrary1.Class1">
    <property name="Test" value="MyTestValue"/>
  </object>
</objects>

Adium behind firewall

At work the company firewall blocked the ports used by Adium to connect to the different IM services. One google later I was one happy user, information on where to find the screens to edit the preferences and which checkboxes to use can be found here.

Windows update yet again

So this was going a bit too easy. After installing a fresh copy of Windows XP, including SP2. I went to the update site which prompted me to install SP3, which I did. No problems so far, yet after the new service pack being deployed to the system windows update refused to install any further updates. It found, listed and downloaded them fine but every installation failed. Long story short, if you’re in this situation open up a command prompt. Click start, run, type in cmd and then click ok. In the command prompt type in regsvr32 %windir%system32wups2.dll and hit enter, this registers that dll. Go to the windows update site now, and you’ll have no problems.

If you have xp 64 the dll is located here: %windir%syswow64wups2.dll.

This was after I tried my earlier solution which you can find here.

Where does Outlook Express store email and contacts

At least three months have past since I had to rescue a PC in the family, a new record. One thing I keep forgetting is where, under Windows XP, Outlook Express stores its data. So I’m writing it down here for further reference.

Email messages can be found here: C:Documents and Settings(user name)Local SettingsApplication DataIdentities (under a sub folder there called Outlook Express). The files have a *.dbx extension.

The contact list can be found here: C:Documents and Settings(user name)Application DataMicrosoftAddress Book. The file has a *.wab extension, and it appears it’s prefixed with the user name.