Creating a Azure Mobile Service (also using OData) to create a generic BaseController for CURD operations.
Product that I am currently working on require Azure Mobile Service, as we have mobile app created with Xamarin using Azure Mobile Services to sync down the reference data. This is using .net 4.5
I am using exciting entities in the database, utilising exciting entities with Entity framework is quit easy, I just need to disable migrations in Mobile Service project – just to be safe.
This is my base entity is like
public abstract class EntityBase : EntityData, ICreateEntityBase, IModifyEntityBase { public string CreatedBy { get; set; } public string UpdatedBy { get; set; } } public interface ICreateEntityBase { string CreatedBy { get; set; } } public interface IModifyEntityBase { string UpdatedBy { get; set; } }
EntityData is part of Microsoft.WindowsAzure.Mobile.Service.
This will be my sample Question entity.
[Table("Question")] public class Question : EntityBase { public string Caption { get; set; } public string QuestionType { get; set; } public bool IsRequired { get; set; } }
This is how my Glabal.asax.cs looks like
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(); } }
I am using WebApiConfig.Register() to register my dependancies using Autofac, later I will inject them to my controllers
public static class WebApiConfig { public static void Register() { var options = new ConfigOptions(); var config = ServiceConfig.Initialize(new ConfigBuilder(options, (configuration, builder) => { builder.RegisterType().As(); ........................ ........................ builder.RegisterType().AsImplementedInterfaces().InstancePerLifetimeScope(); })); Database.SetInitializer(null); // Ignore the migrations, let me know if there is a better way..... } }
My DbContext is like below
public class MobileServiceContext : DbContext { private const string ConnectionStringName = "Name=Questions"; public MobileServiceContext() : base(ConnectionStringName) { } public DbSet Questions { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.HasDefaultSchema("Questions"); modelBuilder.Conventions.Add(new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>("ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString())); } }
I will create the BaseController extending the TableController.
[MobileAppController] public class BaseController : TableController where T : class, ITableData, new() { protected override void Initialize(HttpControllerContext controllerContext) { base.Initialize(controllerContext); MobileServiceContext context = new MobileServiceContext(); // TODO : DI this in the constractor DomainManager = new EntityDomainManager(context, Request, Services); } public readonly IDateService DateService; public BaseController(IDateService dateService) { DateService = dateService; } // GET tables/{Table} public IQueryable GetAll() { return Query(); } // GET tables/{Table}/{id} public SingleResult GetSingle(string id) { return Lookup(id); } // PATCH tables/{Table}/{id} public Task Patch(string id, Delta model) { return UpdateAsync(id, model); } // POST tables/{Table} public async Task Post(T model) { T current = await InsertAsync(model); return CreatedAtRoute("Tables", new { id = current.Id }, current); } }
In the actual QuestionController will on ly have the constructor. below is the sample code
public class QuestionController : BaseController { public QuestionController(IDateService dateService) : base(dateService) { } }
Using OData for querying
Now you can use mobile service on your Xamarin app as usual, But if you want to use the same controllers in a web app u can use the OData for your queries.
Get All http://XXXXXXXXXXXXXXXXXX.azurewebsites.net/tables/Question Get All and set the columns to return http://XXXXXXXXXXXXXXXXXX.azurewebsites.net/tables/Question?$select=id,questionType,caption Get By ID http://XXXXXXXXXXXXXXXXXX.azurewebsites.net/tables/ActivityType?id=0B9BD81F-90D7-4C44-B522-B95F0F9C9D48
For more information on odata please click here
yeah its that simple, I think I love OData….