The Inquisitive Coder - Davy Brion’s Blog

Thinking outside of the typical .NET box

Archive for the 'WCF' Category


Easing The Pain Of WCF Debugging

Posted by Davy Brion on 20th August 2008

WCF is pretty cool, i guess. It’s quite powerful, and it’s so configurable it even has options to control the speed of the CPU fans of the users of your service. Ok, maybe you can’t really configure that, but with approximately 12.4 billion WCF configuration settings available to you, who knows? But the biggest problem i have with WCF is the painful debugging experience when something goes wrong.

Ever got a client-side exception that looked like this?

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +73
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +110

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +183
System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +54
System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +32
System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count, TimeSpan timeout) +32
System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count) +53
System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +37
System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +131
System.Net.Security.NegotiateStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +28
System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +223

[IOException: The read operation failed, see inner exception.]
System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +333
System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count) +79
System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +72

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +7594687
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +275

Rather messy, no? Does it give you any clue as to what could possibly be wrong? Nope. This particular client-side exception occurs when something goes wrong server-side, at some point after you’ve already returned your return value in your service implementation. Of course, you don’t actually see it happening server-side. So i tried setting IncludeExceptionDetailInFaults to true on the service implementation… didn’t make a difference. I set IncludeExceptionDetailInFaults to true on the service host but that didn’t work either. Sigh.

After some Live Searching (i was actually googling, but let’s make Microsoft think at least someone outside of Redmond uses Live Search) i discovered that you can enable WCF tracing. Bingo! Why didn’t Juval Lowy’s book mention this? It’s supposed to be the WCF Bible…. Oh well, thanks to Google, i mean Live Search, we now know how to enable WCF’s tracing:

  <system.diagnostics>

    <trace autoflush=true />

    <sources>

      <source name=System.ServiceModel

              switchValue=Information, ActivityTracing

              propagateActivity=true>

        <listeners>

          <add name=wcfTraceListener type=System.Diagnostics.XmlWriterTraceListener initializeData=WcfTrace.svclog />

        </listeners>

      </source>

    </sources>

  </system.diagnostics>

You can also use the Service Configuration Editor tool which is available in the Windows SDK, but spare yourself the pain of that tool and just copy/paste this xml in your config file.

Now run the service again, and do whatever it was that triggered the weird client-side exception. After the exception occurred, open the WcfTrace.svclog file with either an editor (it’s not very readable though) or with the Microsoft Service Trace Viewer tool (which is not too bad actually).

When i opened my trace output, i immediately saw a red item in the Activity list… so i clicked on it, and i finally saw the problem:

There was an error while trying to serialize parameter http://tempuri.org/:ProcessReadOnlyRequestsResult. The InnerException message was ‘Maximum number of items that can be serialized or deserialized in an object graph is ‘65536′. Change the object graph or increase the MaxItemsInObjectGraph quota. ‘. Please see InnerException for more details.

There we go… the client-side exception was terribly useless, but this is the best kind of exception: not only is it clear about what’s wrong, it even gives you the solution to the problem. Btw, if you get that client-side exception, it doesn’t mean that your problem will be the same as the one listed here. It could literally be anything if it doesn’t happen inside of your service implementation. I’ve seen the same client-side exception when one type somewhere in the object graph didn’t have a DataContract attribute, for instance.

So anyways, do yourself a favor and enable WCF tracing while you’re still in development… it could save you a lot of time.

Oh and bonus points go to whoever points out which of WCF’s many configuration settings actually make the real exception appear in the client-side stacktrace :)

Posted in WCF | 8 Comments »

Batching++

Posted by Davy Brion on 30th July 2008

The usual example:

                dispatcher.Add(new GetProductCategoriesRequest(), new GetSuppliersRequest());

                View.ProductCategories = dispatcher.Get<GetProductCategoriesResponse>().ProductCategories;

                View.Suppliers = dispatcher.Get<GetSuppliersResponse>().Suppliers;

                View.DataBind();

Thanks to my request/response service layer, those are two service requests that will be performed in one service call. On the server side, these two requests are dealt with separately. But they merely retrieve data from the database. Wouldn’t it be cool if those 2 queries were performed in one database roundtrip instead of two? Wouldn’t it be cool if we could batch the queries that will be performed by read-only service requests into a single database roundtrip? It sure as hell would be. Implementing this was one of those irresistible challenges you just can’t say no to, so from now on we can actually do this. I’m not gonna get into the actual implementation of how I got it working (check the code in the library for that if you’re interested), but i will show you how you can do this in your application.

First of all, if you have requests that merely return data, inherit from ReadOnlyRequest instead of the usual Request type:

    [Serializable]

    public class GetProductCategoriesRequest : ReadOnlyRequest {}

 

    [Serializable]

    public class GetSuppliersRequest : ReadOnlyRequest {}

The handlers for these requests should inherit from the ReadOnlyRequestHandler base class instead of the usual RequestHandler class. Btw, my ReadOnlyRequestHandler class inherits from my UoWRequestHandler class, which requires a IUnitOfWork instance to be passed to the constructor. So we need to put an IUnitOfWork parameter into the constructor along with our other dependencies if we want the IOC container (or the request processor) to pass us a valid IUnitOfWork instance.

    public class GetProductCategoriesHandler : ReadOnlyRequestHandler<GetProductCategoriesRequest>

    {

        private readonly IRepository<ProductCategory> repository;

 

        public GetProductCategoriesHandler(IUnitOfWork unitOfWork, IRepository<ProductCategory> repository)

            : base(unitOfWork)

        {

            this.repository = repository;

        }

 

        public override void AddQueries(IQueryBatcher queryBatcher, GetProductCategoriesRequest request)

        {

            queryBatcher.AddCriteria(“categories”, repository.CriteriaForAll());

        }

 

        public override Response GetResults(IQueryBatcher queryBatcher, GetProductCategoriesRequest request)

        {

            var categories = queryBatcher.GetEnumerableResult<ProductCategory>(“categories”);

 

            return new GetProductCategoriesResponse { ProductCategories = categories.ToDTOs() };

        }

    }

The ReadOnlyRequestHandler class defines two abstract methods: the AddQueries and GetResults method. Both are passed an instance of IQueryBatcher and the actual request object so you can use the request parameters if there are any.

In the AddQueries method, you simply add the queries this request needs to perform to the batcher (with a string key value of course for later retrieval), and in the GetResults method you can get the results (with the key values used in AddQueries) back from the batcher and you can construct your Response object. The GetResults method will be called after each ReadOnlyRequestHandler for the current request batch has added the queries to be performed to the batcher. The queries are then all executed, and each ReadOnlyRequestHandler will have its GetResults method called so each handler can construct the proper response.

And that’s it basically… The calling code doesn’t even change.

Now there are obviously some limitations. If you mix ReadOnlyRequests with other Requests, then each ReadOnlyRequest will be handled as if it were a regular Request and they will each get their very own IQueryBatcher instance. I don’t think there’s any strategy to automagically determine which ReadOnlyRequests can be batched together while still correctly executing the other Requests since those requests might influence the results of ReadOnlyRequests that are present further in the batch.

Anyways, you can find an updated version of the library here. Check it out, it’s some pretty slick shit, if i do say so myself ;)

Note: i only added this stuff today, so the previous build (080729) doesn’t have this yet, in case you only downloaded that today, and the stats show that some of you actually did download it ;)

Posted in NHibernate, Performance, Software Development, WCF | 1 Comment »

The Request/Response Service Layer

Posted by Davy Brion on 27th July 2008

Introduction

When you’re trying to design a service layer API, there are two things you always need to be very careful of. The first is making sure the API isn’t chatty. A service layer is usually deployed on another physical machine than the client layer, so you want clients to be able to do everything they need to do with a minimum of roundtrips, because those are after all rather expensive. The second thing you want to avoid is the implicit coupling between the client of the service and the service itself. In your quest to avoid the chatty interface, you might start grouping several service operations together in more coarse-grained operations to avoid the chatty communication that might otherwise occur. This can be good from a performance point of view, but it usually introduces a certain implicit coupling between the service and the client, because a specific grouping of operations might be beneficial to one client, but might be completely inappropriate to another type of client of the service.

I really had difficulties coming up with an approach that offered nice coarse-grained service interfaces while at the same time making sure the interfaces weren’t too ‘driven’ by a client’s specific requirements. So i basically wanted a way to keep my service operations as specific as they could be (very fine-grained), while avoiding the pitfall of chatty communication by batching calls to the service layer together whenever it makes sense from the client’s point of view. I eventually ended up with an approach that i’ve already documented here and here. Read those posts first before continuing with this post because the rest of this post builds upon the content of the previous posts.

The idea is to basically consider each service operation as a request which can have a response. For each request that you define, you need to provide a handler which does whatever it needs to do to handle the request and returns a response, or an empty response if no response is needed for a specific request. You then only need one service method which receives incoming requests, delegates them to the proper handlers, and returns each response in the order of the incoming requests. On a side note: this approach probably doesn’t sit well with many SOA people, but then again, i couldn’t care less about SOA. I just want good software no matter what acronym i can use to describe it.

Anyway, i like this approach so much that i wanted to make it available to whoever is interested in it. You can find it in my open source library which you can find here. I won’t go into the details of the implementation, because those have mostly been covered already in my previous posts on this subject. The rest of this post focuses solely on how you can use this approach in your projects.

Defining Requests and Responses

The following two base classes need to be used to define request and response types:

namespace Brion.Library.Common.Messaging

{

    [Serializable]

    public abstract class Request {}

 

    [Serializable]

    public abstract class Response { }

 

}

Suppose you have a service operation that retrieves a list of products based on some parameters the user could provide in the UI. You would define the request like this:

    [Serializable]

    public class GetProductOverviewsRequest : Request

    {

        public string NamePattern { get; set; }

        public int? CategoryId { get; set; }

        public int? SupplierId { get; set; }

    }

And the response would look like this:

    [Serializable]

    public class GetProductOverviewsResponse : Response

    {

        public ProductOverviewDTO[] Products { get; set; }

    }

Keep in mind that these types always need to be marked with the Serializable attribute and that these types need to be in an assembly that you can share between both the client and the service.

Handling Requests

Incoming requests are handled by a class which implements the IRequestProcessor interface:

namespace Brion.Library.Common.Messaging

{

    public interface IRequestProcessor : IDisposable

    {

        Response[] Process(params Request[] requests);

    }

}

For each request that is received, the request processor will create a request handler which must be of the type IRequestHandler<TRequest> where TRequest is the type of the request instance. The request object is then passed along to the handler’s Handle method, which will return a proper Response object.

The simplest way to create a request handler is to inherit from the RequestHandler<TRequest> class, like this:

    public class GetProductOverviewsHandler :

        Brion.Library.ServerSide.Messaging.RequestHandler<GetProductOverviewsRequest>

    {

        public IProductRepository ProductRepository { get; private set; }

 

        public GetProductOverviewsHandler(IProductRepository productRepository)

        {

            ProductRepository = productRepository;

        }

 

        public override Response Handle(GetProductOverviewsRequest request)

        {

            var products = ProductRepository.FindAll(request.NamePattern, request.SupplierId,

                request.CategoryId);

 

            return new GetProductOverviewsResponse { Products = products.ToOverviewDTOs() };

        }

    }

The request processor uses the Castle Windsor Inversion Of Control container to resolve and create the instances of the request handler types. This allows you to use dependency injection for your request handlers. In the example posted above, you can see that the constructor of the handler takes an IProductRepository instance. Because the Windsor container also knows about the IProductRepository component in my application, it can correctly instantiate the GetProductOverviewsHandler instance with a valid IProductRepository instance. Keep in mind that this is optional though. You don’t have to use dependency injection for your request handlers if you don’t want to.

If you do want to use it, your application will have to use the same Windsor container instance as this library does. To make this possible, the library contains the following class:

namespace Brion.Library.Common

{

    public static class IoC

    {

        private static IWindsorContainer container = new WindsorContainer();

 

        /// <summary>

        /// Gets/Sets the current Windsor container. Applications can either use

        /// the reference to the container that this property provides, or they

        /// can set their own reference through the setter.

        /// </summary>

        public static IWindsorContainer Container { get; set; }

    }

}

By default, an empty container is created which you can access (and thus, configure) through the IoC.Container property. Or if you want the library to use your own Windsor container instance you can simply set the instance and then the library will use your container. For the moment, it is not possible to use another container (like StructureMap or Unity) yet, but that possibility might be added if people want it, or if someone submits a patch :)

Obviously, you need to register your request handlers somewhere in your application code, preferably before you start hosting the service layer. You can do that like this:

            Brion.Library.ServerSide.ComponentRegistration

                .RegisterRequestHandlersFrom(Assembly.GetExecutingAssembly());

That basically registers each valid request handler (each type that inherits from the RequestHandler class provided by the library) that is present in the given assembly. You can also very easily provide your own custom base request handler, in case you want to provide some extra stuff. You’d simply need to inherit from the library’s RequestHandler class, add whatever it is you need, and let your request handlers inherit from your new class instead of directly inheriting from the library’s RequestHandler.

Hosting The Service Layer

There are a lot of options for hosting the service layer. Most people will probably host it as a WCF service so we’ll cover that scenario here. The service contract looks like this:

namespace Brion.Library.Common.WCF

{

    [ServiceContract]

    public interface IWcfRequestProcessor

    {

        [OperationContract]

        [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]

        Response[] Process(params Request[] requests);

    }

}

This is practically identical to the IRequestProcessor interface shown earlier in the article. The difference is that IRequestProcessor uses no WCF attributes. The actual implementation of IRequestProcessor is completely decoupled from WCF as well so you can use this approach without having to use WCF if you want to. The implementation of the IWcfRequestProcessor simply forwards each call to the real request processor.

Notice the usage of the KnownTypeProvider class. This makes sure that each of your Request or Response derived types will be properly recognized as a KnownType. All you have to do is register them, like this:

            KnownTypeProvider.RegisterDerivedTypesOf<Request>(sharedAssembly);

            KnownTypeProvider.RegisterDerivedTypesOf<Response>(sharedAssembly);

This registers each Request or Response derived type from the sharedAssembly reference (which is a reference to the shared assembly containing the request and response types) with the KnownTypeProvider. You need to do this before you start hosting the service. It’s best to combine this task with the registration of your request handlers.

The actual hosting of the service is typical WCF and is entirely up to you. Here’s a simple example of self-hosting the service in a console app:

    <services>

      <service name=Brion.Library.ServerSide.WCF.WcfRequestProcessor behaviorConfiguration=MyBehavior>

        <endpoint contract=Brion.Library.Common.WCF.IWcfRequestProcessor binding=netNamedPipeBinding

              bindingConfiguration=MyNamedPipeBinding address=net.pipe://localhost/RequestProcessor/>

      </service>

    </services>

            using (var host = new ServiceHost(typeof(WcfRequestProcessor)))

            {

                host.Open();

 

                Console.WriteLine(“press ENTER to quit”);

                Console.ReadLine();

            }

You’ll most likely prefer an alternative way of hosting the service, but again, that is entirely up to you and is typical WCF stuff. All you need to know is that the service contract is the Brion.Library.Common.WCF.IWcfRequestProcessor interface, and the actual implementation of the service is the Brion.Library.ServerSide.WCF.WcfRequestProcessor class.

Communicating With The Service Layer

In your client layer, you can choose between using a direct proxy type for the IWcfRequestProcessor service, or you can use the Dispatcher class. The Dispatcher class is somewhat of a wrapper around the direct proxy to make it easier to use and to get a nicer syntax. The Dispatcher class implements the IDispatcher interface:

namespace Brion.Library.ClientSide.Messaging

{

    public interface IDispatcher : IDisposable

    {

        IEnumerable<Request> Requests { get; }

        IEnumerable<Response> Responses { get; }

 

        void Add(Request request);

        void Add(params Request[] requestsToAdd);

        void Add(string key, Request request);

        TResponse Get<TResponse>() where TResponse : Response;

        TResponse Get<TResponse>(string key) where TResponse : Response;

        TResponse Get<TResponse>(Request request) where TResponse : Response;

        void Clear();

    }

}

There are 3 implementations of this interface. The first is the Dispatcher class itself, which has a dependency on an IRequestProcessor instance. The second is the WcfDispatcher class which inherits from the Dispatcher class and will supply its base class with a RequestProcessorProxy instance to satisfy the IRequestProcessor dependency. The third implementation is the DispatcherStub class, which is only useful for your tests. If you want to use dependency injection through the container, you can register the correct components at client start-up time like this:

            Brion.Library.ClientSide.ComponentRegistration.RegisterDispatcherForWcfUsage();

The container will then have the correct configuration to provide you with IDispatcher instances that will correctly use the RequestProcessorProxy underneath. If you don’t want to use the container client-side, you can simply instantiate instances of the WcfDispatcher class.

So, how do you use the dispatcher? It’s pretty easy really. Suppose you want to dispatch two requests to the service, you could do so like this:

                dispatcher.Add(new GetProductCategoriesRequest(), new GetSuppliersRequest());

                View.ProductCategories = dispatcher.Get<GetProductCategoriesResponse>().ProductCategories;

                View.Suppliers = dispatcher.Get<GetSuppliersResponse>().Suppliers;

The requests won’t be dispatched to the service until you actually call one of the Get method overloads for the first time. So you can add as much requests as you like, they won’t be dispatched until you try to retrieve a response. And when those requests are dispatched, it is done in only one roundtrip.

If you just want to dispatch a single request, you could do so like this:

            var request = new GetProductOverviewsRequest

                { NamePattern = name, CategoryId = productCategoryId, SupplierId = supplierId };

            var response = dispatcher.Get<GetProductOverviewsResponse>(request);

            View.Products = response.Products;

Keep in mind that you do need to define the service endpoint in your client-side application’s configuration file. You also need to register the KnownTypes client-side before you start using the Dispatcher or the service proxy in the manner discussed earlier.

Stubbing The Service Layer During Testing

If you write tests for your client-side code, you’ll be glad to hear that i’ve included a DispatcherStub class which makes it easy to prepare responses to return and to inspect requests that were sent from the code you’re testing. The approach i outlined in this post doesn’t really lend itself to easy mocking, so the DispatcherStub class makes it all much easier.

First of all, make sure your client code always uses references of the IDispatcher type instead of directly using the Dispatcher or WcfDispatcher types. Then in your tests, inject DispatcherStub instances instead of real Dispatchers. The DispatcherStub class provides a few extra methods which you can use in your tests:

        [Test]

        public void RetrievesCategoriesAndSuppliersOnLoad()

        {

            var categoriesToReturn = new ProductCategoryDTO[0];

            var suppliersToReturn = new SupplierDTO[0];

 

            dispatcher.SetResponsesToReturn(

                new GetProductCategoriesResponse { ProductCategories = categoriesToReturn },

                new GetSuppliersResponse { Suppliers = suppliersToReturn });

 

            view.Expect(v => v.ProductCategories = categoriesToReturn);

            view.Expect(v => v.Suppliers = suppliersToReturn);

            view.Expect(v => v.DataBind());

 

            mocks.ReplayAll();

            CreateController().Load();

 

            view.VerifyAllExpectations();

            Assert.IsNotNull(dispatcher.GetRequest<GetProductCategoriesRequest>());

            Assert.IsNotNull(dispatcher.GetRequest<GetSuppliersRequest>());

        }

The SetResponsesToReturn and GetRequest methods make it much easier to stub the service layer than traditional mocking would.

Something you’ll often want to test is that requests have been sent with the correct parameters:

            var request = dispatcher.GetRequest<GetProductOverviewsRequest>();

            Assert.AreEqual(productPattern, request.NamePattern);

            Assert.AreEqual(categoryId, request.CategoryId);

            Assert.AreEqual(supplierId, request.SupplierId);

Time to wrap it up

Again, i really like this approach. Unfortunately i haven’t had the chance to use this in a real project yet, but based on my experiments i’m already very happy with it and am looking forward to use this in a real project. If you’d like to use this approach, download the library here, play around with it, try it out, try to break it, and let me know what needs to be fixed/changed/added. Or send patches ;)

Posted in Patterns, Software Development, WCF | 3 Comments »

The Known Type Provider

Posted by Davy Brion on 21st July 2008

Manually dealing with KnownTypes in WCF is a bit of a pain. Well, at least if you have more than a few derived types you want your WCF services to serialize/deserialize. Luckily for us, there is a way to do this automatically. Using the ServiceKnownType attribute you can specify a class and a static method of that class which will provide the Known Types. An example of this can be found on my ever-recurring Process service method:

        [OperationContract]

        [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]

        Response[] Process(params Request[] requests);

This works, but i don’t want to write a class every time i want to specify some known types of a base type in a service method. So i modified that KnownTypeProvider class so that we can now do the following:

            KnownTypeProvider.RegisterDerivedTypesOf<Request>(mySharedAssembly);

            KnownTypeProvider.RegisterDerivedTypesOf<Response>(mySharedAssembly);

This registers each derived type of Request and Response in the mySharedAssembly reference (of type Assembly) with the KnownTypeProvider. You can register as many known types for as many base types as you want. Obviously, you have to do this before you start hosting your service. You also need to do this client-side, before you start using your service proxies.

You’re probably thinking “wait, won’t that return all registered known types for every service call where you use this stuff?”. That wouldn’t be good, so i took care of that. The ServiceKnownType attribute of WCF requires your class to implement a method which receives a parameter of type ICustomAttributeProvider and which returns a list of types. The ICustomAttributeProvider parameter is actually a MethodInfo instance at runtime. This makes it possible to inspect the current service method’s parameters and return type. That information makes it possible to only return the KnownTypes that are relevant to the current service call. All of this sounds expensive with regards to performance, so obviously this is all cached… so you only take the performance hit on the very first request of each service method where you use this.

The KnownTypeProvider makes it extremely easy to register your KnownTypes in a generic way, can be reused across multiple service methods and it only returns the relevant KnownTypes for each service method. And it does so with a minimum of performance overhead.

You can find the code in my public svn repository as a part of my utility library (the tests can be found here). At this moment it is one of the only classes in the library, because i still have to add some other stuff before i’ll put a ‘proper release’ online :)

Posted in WCF | 5 Comments »

Can someone tell me why i shouldn’t drop WCF?

Posted by Davy Brion on 12th July 2008

I’ve written a few posts about WCF lately… mostly about how to batch WCF service calls. In case you didn’t know, i consider batching support a MUST-HAVE feature. Since then, my WCF services all extend the following interface:

    [ServiceContract]

    public interface IService : IDisposable

    {

        /// <summary>

        /// Processes each request within the same service call

        /// </summary>

        /// <param name=”requests”>each request</param>

        /// <returns>the corresponding responses</returns>

        [OperationContract]

        [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]

        Response[] Process(params Request[] requests);

    }

I wanted to keep providing specific service methods for each kind of request, but each service implementation would delegate the handling of the requests to the Process method, which in turn would delegate the handling of the request to a specific request handler type which was associated with the request type. So basically, all of these specific service contracts which extend this service don’t really offer me anything extra.

So now i’m wondering why i’m even bothering with the specific services anymore… it only leads to more work: more service interfaces and more proxies and in the end, everything is routed to the Process method. So what’s the point of these specific services anymore if you don’t have batching support out of the box? If i have to go with a generic Process method to get batching support (again, which i consider a MUST-HAVE feature), why am i even bothering with Services at all? Essentially, i’m using a service bus with WCF. Why shouldn’t i just move to NServiceBus which is actally perfectly suited for this kind of work?

For the record, i’m not trying to flame or anything… i really want to get some answers to the following question: why shouldn’t i drop WCF and the whole service layer thing in favor of a real service bus and Messaging in general?

Posted in WCF | 10 Comments »

Batching WCF calls, Take 2

Posted by Davy Brion on 1st July 2008

The first take was pretty good, after all it got Ayende-d which is the highlight of my blogging career so far :). In his post, he was pretty positive about my implementation, with one small exception:


“About the only thing that I would strive to improve there would be the need to explicitly register request & replies. I would try to get something convention based there. Maybe something like Request, and then have IHandler and route the whole thing through the container again.”

Let’s give that a shot :)

Previously, the base implementation of the service routed the call to the correct RequestHandler like this:

        public Response[] Process(params Request[] requests)

        {

            if (requests == null)

            {

                return null;

            }

 

            var responses = new List<Response>(requests.Length);

 

            foreach (var request in requests)

            {

                Type handlerType = GetHandlerTypeFor(request);

 

                if (handlerType == null)

                {

                    responses.Add(new UnsupportedRequestResponse());

                    continue;

                }

 

                using (var handler = GetHandlerInstance(handlerType))

                {

                    responses.Add(handler.Handle(request));

                }

            }

 

            return responses.ToArray();

        }

 

        public virtual IRequestHandler GetHandlerInstance(Type handlerType)

        {

            return (IRequestHandler)Container.Resolve(handlerType);

        }

 

        public abstract Type GetHandlerTypeFor(Request request);

And then the service implementation would provide an implementation of the GetHandlerTypeFor method. In that implementation, you somehow had to map the type of the incoming Request to a handler. In the code that i posted i used a dictionary-based approach. You could’ve used a couple of if statements as well. The point is that you had to do that mapping which is indeed somewhat annoying.

First, we’ll add a new interface on top of the IRequestHandler interface:

    public interface IRequestHandler : IDisposable

    {

        Response Handle(Request request);

    }

 

    public interface IRequestHandler<TRequest> : IRequestHandler

        where TRequest : Request

    {

        Response Handle(TRequest request);

    }

We also modify the base RequestHandler class to provide a derived generic class:

    public abstract class RequestHandler : Disposable

    {

        protected IUnitOfWork UnitOfWork { get; private set; }

 

        protected RequestHandler(IUnitOfWork unitOfWork)

        {

            UnitOfWork = unitOfWork;

        }

 

        protected override void DisposeObjects()

        {

            if (UnitOfWork != null) UnitOfWork.Dispose();

        }

 

        protected override void ClearReferences()

        {

            UnitOfWork = null;

        }

    }

 

    public abstract class RequestHandler<TRequest> : RequestHandler, IRequestHandler<TRequest>

        where TRequest : Request

    {

        protected RequestHandler(IUnitOfWork unitOfWork) : base(unitOfWork) {}

 

        public abstract Response Handle(TRequest request);

 

        public Response Handle(Request request)

        {

            return Handle((TRequest)request);

        }

    }

The only reason why i still have the base RequestHandler type is to make it easier to register the RequestHandler types with the container (which i’ll show below).

A specific RequestHandler can now be defined like this:

    public class GetProductCategoriesHandler : RequestHandler<GetProductCategoriesRequest>

Right, now we can register all of our RequestHandler types with the container:

        private static void RegisterRequestHandlers()

        {

            foreach (var type in typeof(RequestHandler).Assembly.GetTypes())

            {

                if (type.IsSubclassOf(typeof(RequestHandler)) && type.BaseType.IsGenericType)

                {

                    var serviceType = typeof(IRequestHandler<>).MakeGenericType(type.BaseType.GetGenericArguments());

                    Register(Component.For(serviceType).ImplementedBy(type).LifeStyle.Transient);

                }

            }

        }

So now each generic RequestHandler type is registered through the generic IRequestHandler type.

Our base Service implementation now looks like this:

        public Response[] Process(params Request[] requests)

        {

            if (requests == null)

            {

                return null;

            }

 

            var responses = new List<Response>(requests.Length);

 

            foreach (var request in requests)

            {

                Type handlerType = typeof(IRequestHandler<>).MakeGenericType(request.GetType());

 

                using (var handler = (IRequestHandler)Container.Resolve(handlerType))

                {

                    responses.Add(handler.Handle(request));

                }

            }

 

            return responses.ToArray();

        }

And now you no longer need to map the Request type to the RequestHandler type yourself since the container now takes care of that for us.

Posted in Performance, WCF | No Comments »

The Service Call Batcher

Posted by Davy Brion on 28th June 2008

Picking up where we left off with the WCF batching… We had the following code client-side to execute a few service methods with one request:

            var results = service.Process(new GetProductCategoriesRequest(), new GetProductOverviewsRequest());

            View.ProductCategories = ((GetProductCategoriesResponse)results[0]).ProductCategories;

            View.Products = ((GetProductOverviewsResponse)results[1]).Products;

Similar to my query batcher, i wrote this simple WCFCallBatcher class:

    public class ServiceCallBatcher

    {

        private readonly IService service;

        private readonly Dictionary<string, int> responsePositions = new Dictionary<string, int>();

        private readonly List<Request> requests = new List<Request>();

        private Response[] responses;

 

        public ServiceCallBatcher(IService service)

        {

            this.service = service;

        }

 

        public void Add(string key, Request request)

        {

            requests.Add(request);

            responsePositions.Add(key, requests.Count - 1);

        }

 

        public T Get<T>(string key) where T : Response

        {

            if (responses == null) ExecuteRequests();

            return (T)responses[responsePositions[key]];

        }

 

        private void ExecuteRequests()

        {

            responses = service.Process(requests.ToArray());

        }

    }

and now we can rewrite the client code like this:

            var batcher = new ServiceCallBatcher(service);

            batcher.Add(“categories”, new GetProductCategoriesRequest());

            batcher.Add(“products”, new GetProductOverviewsRequest());

            View.ProductCategories = batcher.Get<GetProductCategoriesResponse>(“categories”).ProductCategories;

            View.Products = batcher.Get<GetProductOverviewsResponse>(“products”).Products;

Yes, we’ve got more lines of code now, but i like this block of a code a lot more than the earlier one. This is much more readable.

Posted in Performance, WCF | No Comments »

Batching WCF calls

Posted by Davy Brion on 26th June 2008

What happens if you have the following code client-side:

            View.ProductCategories = service.GetProductCategories();

            View.Products = service.GetProductOverviews();

The service variable is a reference to a WCF service proxy. This means that this causes 2 remote service calls. I really hate unnecessary/excessive roundtrips, so i would rather retrieve this data from the service in one roundtrip. Unfortunately, this is not something that is supported by WCF out of the box, so if you want to do this you have to do it yourself. There are a couple of options, so i started browsing the web. Once again, it’s Ayende to the rescue. The approach he suggests is a bit cumbersome compared to how you’d normally design your services, but it does offer a great deal of flexibility and it allows you to nicely batch your requests. So i figured i should try implementing this approach.

The idea is to provide a service method that looks like this:

        Response[] Process(params Request[] requests);

Each Request corresponds to what used to be a normal service method, and this method returns a Response for each Request. In Ayende’s post, he suggest offering this as the only service method. I won’t go that far though. I’ll offer this method, and each ‘normal’ method allthough those methods will also use Request types as input variables and Response types as return values. The idea is to be able to use each service method individually, or to have multiple service methods executed in one roundtrip through the Process method.

We need a way to define Requests and Responses, so we create the following classes:

    [Serializable]

    public abstract class Response { }

 

    [Serializable]

    public abstract class Request {}

For now, these are empty but i’m pretty sure i’ll add a few members to these later on. Then we define specific Request and Response types for the functionality our service needs to offer:

    [Serializable]

    public class GetProductCategoriesRequest : Request {}

 

    [Serializable]

    public class GetProductOverviewsRequest : Request

    {

        public int? ProductCategoryId { get; set; }

    }

    [Serializable]

    public class GetProductCategoriesResponse : Response

    {

        public ProductCategoryDTO[] ProductCategories { get; private set; }

 

        public GetProductCategoriesResponse(ProductCategoryDTO[] productCategories)

        {

            ProductCategories = productCategories;

        }

    }

 

    [Serializable]

    public class GetProductOverviewsResponse : Response

    {

        public ProductOverviewDTO[] Products { get; private set; }

 

        public GetProductOverviewsResponse(ProductOverviewDTO[] products)

        {

            Products = products;

        }

    }

We then create a base interface that each service will implement (along with more specific service interfaces):

    [ServiceContract]

    public interface IService : IDisposable

    {

        /// <summary>

        /// Processes each request within the same service call

        /// </summary>

        /// <param name=”requests”>each request</param>

        /// <returns>the corresponding responses</returns>

        [OperationContract]

        [ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]

        Response[] Process(params Request[] requests);

    }

The KnownTypeProvider is responsible for providing a list of types that should be treated as KnownTypes during serialization/deserialization. We could also list each type that derives from Response/Request but that will become a long list, so i went for this approach. The code of the KnownTypeProvider class looks like this:

    public static class KnownTypeProvider

    {

        private static readonly List<Type> knownTypes;

 

        static KnownTypeProvider()

        {

            knownTypes = BuildListOfKnownTypes();

        }

 

        private static List<Type> BuildListOfKnownTypes()

        {

            Assembly containingAssembly = typeof(KnownTypeProvider).Assembly;

 

            return containingAssembly.GetTypes()

                .Select(t => t)

                .Where(t => t.IsSubclassOf(typeof(Request)) || t.IsSubclassOf(typeof(Response)))

                .ToList();

        }

 

        public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)

        {

            return knownTypes;

        }

    }

Our real service now looks like this:

    [ServiceContract]

    public interface IProductsService : IService

    {

        [OperationContract]

        GetProductCategoriesResponse GetProductCategories(GetProductCategoriesRequest request);

 

        [OperationContract]

        GetProductOverviewsResponse GetProductOverviews(GetProductOverviewsRequest request);

    }

To handle these requests, i came up with the following RequestHandler type:

    public abstract class RequestHandler : Disposable, IRequestHandler

    {

        public IUnitOfWork UnitOfWork { get; private set; }

 

        protected RequestHandler(IUnitOfWork unitOfWork)

        {

            UnitOfWork = unitOfWork;

        }

 

        protected override void DisposeObjects()

        {

            if (UnitOfWork != null) UnitOfWork.Dispose();

        }

 

        protected override void ClearReferences()

        {

            UnitOfWork = null;

        }

 

        public abstract Response Handle(Request request);

    }

And the implementation of one of these concrete RequestHandlers looks like this:

    public class GetProductOverviewsHandler : RequestHandler

    {

        public ProductRepository ProductRepository { get; private set; }

 

        public GetProductOverviewsHandler(IUnitOfWork unitOfWork, ProductRepository productRepository)

            : base(unitOfWork)

        {

            ProductRepository = productRepository;

        }

 

        public override Response Handle(Request request)

        {

            var typedRequest = (GetProductOverviewsRequest)request;

 

            if (typedRequest.ProductCategoryId.HasValue)

            {

                var fetchStrategy = new FetchStrategy

                    { Association = “Supplier”, FetchMode = FetchMode.Join };

                var productOverviews = ProductRepository.FindAllByCategory(

                    typedRequest.ProductCategoryId.Value, fetchStrategy);

                return new GetProductOve