My Silverlight 4 Reference Architecture: Querying

My original intention was to use WCF Data Services combined with NHibernate on the query side. For one, because it allows you to filter the result set using a subset of the LINQ functionality at the Silverlight client. But also because it will transfer the resulting entity set including any associated relationships as one network operation; which is something that WCF RIA Services can't do. In essence it means that you don't have to explicitly convert entities to DTOs, but I kept the term in the diagram

However, in reality this subset of LINQ is a bit too limited. For instance, filtering an entity set based on some criteria on one of its associations (through the Any() operation) is not possible. WCF Data Services does support Service Operations, but I have never managed to get anything other than the MSDN examples to work. In fact, the Add Service Reference does not even support service operations. That's why I introduced a dedicated WCF Query Service.

Nevertheless, having a service class with a multitude of operations, all using one of the Repositories is a great recipe for getting a bloated class. That's why every query operation is handled by a dedicated Service Action class that handles the interaction with the repositories, preferably using an implementation of the Specification pattern. Such a Specification encapsulates (a potentially very complex) query on an IQueryable<T> implementation and returns the matching entities:

The beauty of this pattern is that you can easily verify its behavior by passing in an arbitrary in-memory collection and observing the resulting subset from a unit test. At run-time, the repository will simply pass an IQueryable<T> implementation that directly talks to LINQ-to-NHibernate.

I already blogged about the combination of NHibernate and WCF Data Services, so I will refrain from repeating myself. However, one thing to remember when working with Silverlight, is that it doesn't really work well with services that throw FaultExceptions. In fact, it does not even understand them and treat them like a generic error 500. Luckely, the MSDN library contains a great article that explains how to introduce a custom Endpoint Behavior to overcome this. For the lazy people among us, get the code from my CQRS example so that you tuck its extension element in your web.config like this:

Share on

Leave a Comment

You May Also Enjoy

The characteristics of a great projection implementation
Over the course of the last two years I’ve written numerous articles on the good, the bad and the ugly of Event Sourcing as well as on our experiences building and maintaining a distributed enterprise-class based on this increasingly popula...

Over the last couple of months I’ve heard and read quite a few statements that say that Dependency Injection frameworks are bad things that you should avoid like the plague. In my opinion that’s just a result of rejecting something because it has been misused too long. Don’t get me wrong. I’ve be...

When your project, product or component gets sufficiently big that it has a large impact on the rest of the organization, you’ll automatically get faced with lots of internal and external distractions. Other teams might want to get that pull request merged as soon as possible, all kinds of questi...

It has been almost a year since version 4.19, the last functional release of Fluent Assertions was shipped. Not because of a lack of feature requests, but simply because this new version has cost me all the private time I had. My main goal of this release was to repair some of the design mistakes...