How to do it: Using the Reflection provider to create a Data Service using an in-memory data source

Description and code samples
Table of Contents
Operations
Data model definition file (InMemoryDataModel.cs)

The data model that is based on arbitrary classes as long as those classes have the primary key configured, through the use of the DataServiceKeyAttribute attribute .

How to do it
using System;
using System.ComponentModel;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Services;
using System.Data.Services.Common;
using System.Collections.Generic;

namespace WCF.Data.Services
{
    [DataServiceKeyAttribute("Id")]
    public class Order
    {
        public int Id { get; set; }
        public string CustomerName { get; set; }
        public IList<Item> Items { get; set; }
    }

    [DataServiceKeyAttribute("Id")]
    public class Item
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
    }

}
Data Container (InMemoryDataContainer.cs)

The data context to be used in the DatService<T> is simulated by having a data container structure with:

  • Several instances of class types defined on the Data Model populated with data;
  • Those classes exposed as objects that implement the IQueryable<T> interface.
How to do it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WCF.Data.Services
{
    public partial class InMemoryDataContainer
    {
        #region Populate Service Data
        static IList<Order> _orders;
        static IList<Item> _items;
        static InMemoryDataContainer()
        {
            _orders = new Order[]{
              new Order(){ Id=0, CustomerName = "Peter Franken", Items = new List<Item>()},
              new Order(){ Id=1, CustomerName = "Ana Trujillo", Items = new List<Item>()}};
            _items = new Item[]{
              new Item(){ ProductName="Chai", Quantity=10 },
              new Item(){ ProductName="Chang", Quantity=25 },
              new Item(){ ProductName="Aniseed Syrup", Quantity = 5 },
              new Item(){ ProductName="Chef Anton's Cajun Seasoning", Quantity=30}};
            _orders[0].Items.Add(_items[0]);
            _orders[0].Items.Add(_items[1]);
            _orders[1].Items.Add(_items[2]);
            _orders[1].Items.Add(_items[3]);
        }
        #endregion

        public IQueryable<Order> Orders
        {
            get { return _orders.AsQueryable<Order>(); }
        }
        public IQueryable<Item> Items
        {
            get { return _items.AsQueryable<Item>(); }
        }
    }

}
The WCF data service definition file (WcfDataService2.svc.cs)

The DataService<T> class is defined using the data container structure mencioned above.

How to do it
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace WCF.Data.Services
{
    public class WcfDataService2 : DataService<InMemoryDataContainer>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.

            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}
The WCF data service definition markup file (WcfDataService2.svc)
How to do it

<%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service="WCF.Data.Services.WcfDataService2" %>