In continuing to extend this app, I created a new repository type. Because I already had the IDataRepository abstraction in place, I thought it would be interesting to create a ServiceStackRepository from it.
Service Stack is an open-source web services framework that allows you to do messaging similar to WCF. I was happy that like WCF, it also allows for self-hosting. This is really a no-brainer since messaging technologies that allow cross process communication shouldn’t count on a web server as the only end point.
First, the changes I had to make. I try to follow the open-closed principle in writing my code. There is not much change in the existing projects, other than some refactoring, such as creating a new project, GettingReady.Core, and moving the 2 repositories (InMemoryRepository, ServiceStackRepository) to it. Other than that, there should be minimal changes to the existing code. The new additions include:
- New console application, GettingReady.ServStack.Service. Hosts the service stack web service API.
- New repository type, ServiceStackRepository, to communicate with the service. This makes use of the C# client libraries that come with Service Stack.
- Additional collection element in app.config to specify the different repository types and the default one to use. See below.
<repository name=“InMemoryRepository“ type=“GettingReady.Core.InMemoryRepository, GettingReady.Core“ />
<repository name=“ServiceStackRepository“ type=“GettingReady.Core.ServiceStackRepository, GettingReady.Core“ />
The Service Stack framework also comes with its own IoC container (Funq) and its own ORM (OrmLite). Both are pretty simple to use and worked out well in this example. SS also makes it easy to create RESTful services. However, unlike WCF, which allows you to define routes based on procedures, SS allows you to define routes based on the DTO itself. This somewhat threw me off for a bit because I was trying to have the parameters passed via the route auto fill the service method parameters. This works well in WCF. However, with SS, additional params passed via the route are expected as properties on the DTO itself. Because I didn’t want to alter the shared model classes I was using as the DTO, I ended up inheriting it and then adding to it the property I was passing in the route. Interestingly, passing a base type where a derived type was expected, did not break the service contract, which I believe it would in WCF. Another positive was that the route was a combination of the url and the HTTP verb. So I could add a GET and a POST to the same url and pass different DTO to each action. You can build very clean API’s with that.