To create a read-only Data Service Provider (or DSP) you need to implement two Data Services interfaces: IDataServiceMetadataProvider to provide the metadata and IDataServiceQueryProvider to handle the queries.

But first Data Services needs a way to find your implementations.

IServiceProvider

Data Services locates these interfaces using the IServiceProvider interface. 

Probably the best way to hook into this is to create your own class that derives from DataService<T>, and implement the IServiceProvider interface so Astoria can use that to locate your DSP interfaces:

public class DSPDataService<T>: DataService<T>, IServiceProvider
{
   public object GetService(Type serviceType)
   {
      if (serviceType == typeof(IDataServiceMetadataProvider))
      {
         return …
      }
      else if (serviceType == typeof(IDataServiceQueryProvider))
      {
         return …
      }
      else
      {
         return null;
      }      
   }
}

Of course how this method actually works depends a lot upon your implementation. Which we will come back to later.

But this is the starting point, and then you, or your customer, can add a Data Service to your web application or WCF app, and simply change it to derive from your class rather than the standard DataService<> like this:

public class DemoDSPDataService : DSPDataService<DSPContext>
{
   // This method is called only once to initialize
   // service-wide policies.
   public static void InitializeService(
       DataServiceConfiguration config
   )
   {
      // TODO: replace this sample configuration with
      // real configuration
      config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
      config.DataServiceBehavior.MaxProtocolVersion =
         DataServiceProtocolVersion.V2;
      config.DataServiceBehavior.AcceptProjectionRequests = true;
   }
}

Here we've hooked the Data Service up to our custom DSP.

Great.

Of course we’ve got some work to do to actually make it work.

But before we go any further lets cover data sources....

Where does the data actually come from?

If you look closely at this code:

public class DemoDSPDataService : DSPDataService<DSPContext>
{

You might wonder what DSPContext is exactly.

Well it is the thing that actually represents your underlying data source, so if could be called anything.

For example if you wrote a custom DSP for the Entity Framework*, DSPContext would be a class derived from System.Data.Objects.ObjectContext.

*NOTE: There is no reason to do this, because Data Services includes an implementation for EF in the box.

If your DSP allows for the underlying data source to be customized in a strongly typed way like EF you should create a generic DSPDataService class as above, and add a generic constraint, limiting T to classes that derive from one of your Data Sources:

public class DSPDataService<T>: DataService<T>, IServiceProvider
                       where T: MyDataSource

If however the data-source is fixed and you don’t need a strongly typed sub-class, then something like this would be all you need:

public class DSPDataService: DataService<MyDataSource>,
                             IServiceProvider

As you can see how you write this class depends upon your capabilities.

Next time

In Part 3 we will look at implementing IDataServiceMetadataProvider…

You can find links to all the posts in the series here.