Whenever I find myself implementing a series of interfaces to plug into a framework or server, I always find myself wondering how the server will call my implementations.
For me this is about forming a mental model to simplify how I think about what I’m doing.
In fact as I’ve been doing this DSP series I’ve come up with a sort of mental model for how Queries are handled in a Data Service.
Here is some PSEUDO CODE that captures my mental model of how these interfaces interact.
Imagine a client issues a GET request for /Sample.svc/Products(1)
The first thing that happens (in my model) is that the data service is initialized.
// Locate the IDSP interfaces var dataservice = …; IServiceProvider sp = dataservice as IServiceProvider; if (sp == null) { // some other code I’ll go into another day !!! }
// Get the various DSP interface implementations IDataServiceMetadataProvider mdp = sp.GetService(typeof(IDataServiceMetadataProvider)); IDataServiceQueryProvider qp = sp.GetService(typeof(IDataServiceQueryProvider)); // Set the CurrentDataSource (if necessary) if (qp.CurrentDataSource == null) qp.CurrentDataSource = dataservice.CreateDataService(); // Find the Products resourceSet // (note we actually try for ServiceOperations first // but lets keep this simple) var resourceSet = null; if (!mdp.TryResolveResourceSet(“Products”, out resourceSet)) throw new Exception(“404”);
// Get the queryable for the Products resourceSet IQueryable queryRoot = qp.GetQueryRootForResourceSet(resourceSet);
// Compose expressions onto the IQueryable to represent the // options ($filter/$select etc) specified in the URL queryRoot = Compose(options, queryRoot);
// Start writing response WriteStartODataFeed(); // Enumerate results foreach (object resource in queryRoot) { // Get the ResourceType for resource // NOTE: because of inheritance it might be a resourceType // derived from resourceSet.ResourceType ResourceType type = qp.GetResourceType(type); WriteResource(resource,type); } WriteEndODataFeed();
That’s it take it or leave it.
Hopefully you found this ‘completely made up’ code useful for forming your own mental model of how your DSP will fit into the Data Services framework.
There are some things I’ve left out of the above ‘mental model’ for now, like how ServiceOperations and QueryInterceptors complicate things.
We’ll flesh more of those complications out in future posts.
Next time though it’s time to take our Read/Only strongly typed ResourceSet and make it Read/Write.