DocumentHandler - Behind The Scenes

Mobile Server gives you the option of developing custom code that integrates to your back-end system. One way you can do this is by implementing one or more .NET classes that derive from the abstract DocumentHandler class. This is already described in the documentation along with the other options for back-end integration, but in this post, I'd like to provide some background information on this API. In future posts, I'll discuss some best practices for developing custom DocumentHandlers.

Here's the DocumentHandler API to establish the context:

 public abstract class DocumentHandler
     protected DocumentHandler();
     public abstract string FriendlyName { get; }
     public abstract string GetDocumentDescription(
         string xmlDocument);
     public abstract DocumentResponse Submit(
         string xmlDocument, Guid messageId,
         string deviceId, IPrincipal mobileUser);

When we designed DocumentHandler, we had several design goals in mind:

  • It should be as simple as possible to implement a custom DocumentHandler
  • It should provide as much flexibility as possible
  • It should be testable
  • It should adhere to the .NET Framework Design Guideline that states that you should prefer abstract classes over interfaces (consequently, this is why DocumentHandler is not an interface)
  • It should be CLS compliant

While I personally could wish for even more flexibility, I think we succeeded very well on all the other points. In the Dynamics Mobile Team, we use TDD, so it was particularly important to us that the DocumentHandler API is testable - and it is.

The DocumentHandler constructor is empty, so we don't require you to pass some weird, internal or sealed object as a constructor parameter; on the contrary, in fact we require that your custom DocumentHandler has a default constructor. That makes it super-easy to create a new instance as part of a test:

 MyDocumentHandler sut = new MyDocumentHandler();

All the members of DocumentHandler works on well-known BCL types (string, Guid, and IPrincipal) with the single exception of the Submit method, which returns a DocumentResponse instance, which is a type that we have defined in the same library.

DocumentResponse is a public, non-sealed class with a default constructor, and it works almost exclusively with BCL types such as string, DateTime, bool, etc. Again, there's a single exception in the use of the DocumentResponseStatus enum, but also here we are dealing with a public type that is easily created.

The bottom line is that the entire DocumentHandler API contains only three custom types, and all of those types are very susceptible to unit testing.

In a future post, I will discuss the matter of unit testing custom DocumentHandlers in greater detail.