Wednesday, November 4, 2015

MVC 6 and Dependency Injection on object with Parameters:

Sometimes things aren't obvious like this, which I spent a good portion of the day on.

In Startup.cs in method ConfigureServices(), 


   
            services.AddMvc();
            

            // Uncomment the following line to add Web API services which makes it easier to port Web API 2 controllers.
            // You will also need to add the Microsoft.AspNet.Mvc.WebApiCompatShim package to the 'dependencies' section of project.json.
            // services.AddWebApiConventions();

            // Register application services.
            services.AddTransient();
            services.AddTransient();
#if DNX451
           services.AddSingleton(provider => {
                var endPt = Configuration["Data:DocumentDbConnection:EndpointUrl"];
                var authKey = Configuration["Data:DocumentDbConnection:RWAuthKey"];
                var dbName = Configuration["Data:JobApp:DatabaseName"];
                var collName = Configuration["Data:JobApp:CollectionName"];
                return new JobAppDb(authKey, endPt, dbName, collName);
            }); 
#endif

Sunday, November 1, 2015

11/2015

After Struggling a bit to find documentation on how to create a Repository for DocumentDb in Azure for MVC 6, I decided to publish what I created last night. I hope someone finds this helpful.

-Jonathan Ulfeng

Basic DocumentDb class for Azure, MVC 6:

1. Create a Base Class for the document repository:

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Threading.Tasks;  
 using Newtonsoft.Json;  
 using JobApp33.Util;  
 #if DNX451  
 using Microsoft.Azure.Documents.Client;  
 using Microsoft.Azure.Documents.Linq;  
 using Microsoft.Azure.Documents;  
 using JobApp33.Models;  
 #endif  
 namespace JobApp33.Db  
 {  
   public abstract class DocumentDb  
   {  
     protected string DatabaseName { get; set; }  
     protected string CollectionName { get; set; }  
     protected string EndpointUrl { get; set; }  
     protected string AuthorizationKey { get; set; }  
     protected string CollectionLink => string.Format("dbs/{0}/colls/{1}", DatabaseName, CollectionName);  
     protected string DatabaseLink => string.Format("dbs/{0}", DatabaseName);  
     public DocumentDb()  
     {  
     }  
 #if DNX451  
     protected DocumentClient _client;  
     protected DocumentClient Client  
     {  
       get  
       {  
         if (_client == null)  
           _client = GetClient();  
         return _client;  
       }  
     }  
     protected Database _database;  
     protected Database Database  
     {  
       get  
       {  
         if (_database == null)  
         {  
           _database = ReadOrCreateDatabase();  
         }  
         return _database;  
       }  
     }  
     protected DocumentCollection _collection;  
     protected DocumentCollection Collection  
     {  
       get  
       {  
         if (_collection == null)  
           _collection = ReadOrCreateCollection();  
         return _collection;  
       }  
     }  
     protected DocumentCollection ReadOrCreateCollection()  
     {  
       DocumentCollection col = Client.CreateDocumentCollectionQuery(Database.SelfLink)  
                  .Where(c => c.Id == CollectionName)  
                  .AsEnumerable()  
                  .FirstOrDefault();  
       if (col == null)  
       {  
         col = Client.CreateDocumentCollectionAsync(DatabaseLink, new DocumentCollection { Id = CollectionName }).Result;  
       }  
       return col;  
     }  
     protected Database ReadOrCreateDatabase()  
     {  
       Database db = Client.CreateDatabaseQuery()  
               .Where(d => d.Id == DatabaseName)  
               .AsEnumerable()  
               .FirstOrDefault();  
       if (db == null)  
       {  
         db = Client.CreateDatabaseAsync(new Database { Id = DatabaseName }).Result;  
       }  
       return db;  
     }  
     //private async Task<DocumentClient> GetClientAsync() => new DocumentClient(new Uri(config.EndpointUrl), config.AuthorizationKey);  
     protected DocumentClient GetClient() => new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);  
     #region "CRUD Methods"  
     public async Task<Document> CreateItemAsync<T>(T item) where T : class  
     {  
       return await Client.CreateDocumentAsync(Collection.SelfLink, item);  
     }  
     public async Task<Document> UpsertItemAsync<T>(T item) where T : class  
     {  
       return await Client.UpsertDocumentAsync(Collection.SelfLink, item);  
     }  
     public async Task DeleteItemAsync<T>(string id) where T : class  
     {  
       foreach (Document document in Client.CreateDocumentQuery(  
           CollectionLink,  
           new SqlQuerySpec(  
             string.Format("SELECT * FROM {0} col WHERE col.id = @id", CollectionName),  
             new SqlParameterCollection(new[] { new SqlParameter { Name = "@id", Value = id } }))))  
         {   
           // Optionally, cast to CrawlResult using a dynamic cast  
           var result = (T)(dynamic)document;  
           await Client.DeleteDocumentAsync(document.SelfLink);  
         }  
     }  
     protected async Task<T> GetDocument<T>(string id) where T : class  
     {  
       // Query the documents using DocumentDB SQL.  
       IQueryable<Document> jobApps = from f in Client.CreateDocumentQuery(CollectionLink) where f.Id == id select f;  
       Document d = jobApps.AsEnumerable().FirstOrDefault();  
       T deserializedJobApp = JsonConvert.DeserializeObject<T>(d.ToString());  
       return deserializedJobApp;  
     }  
     #endregion  
 #endif  
   }  
 }  

2. Override that class to handle your poco Objects:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JobApp33.Util;
using Microsoft.Framework.OptionsModel;
using JobApp33.Models;

namespace JobApp33.Db
{

    public class JobAppDb : DocumentDb
    {
        public JobAppDb(IOptions settings) : base()
        {
            this.AuthorizationKey = settings.Options.AuthorizationKey;
            this.EndpointUrl = settings.Options.EndpointUrl;
            this.DatabaseName = settings.Options.JobAppDatabase;
            this.CollectionName = settings.Options.JobAppCollection;
        }
#if DNX451
        public JobApp GetJobApp(string id)
        {
            JobApp jobApp = null;
            Task.Run(async () =>
            {
                jobApp = await this.GetDocument(id);
            }).GetAwaiter().GetResult();
            return jobApp;
        }

        public Microsoft.Azure.Documents.Document UpsertJobApp(JobApp item)
        {
            Microsoft.Azure.Documents.Document doc = null;
            if (item != null)
            { 
                Task.Run(async () =>
                {
                    doc = await this.UpsertItemAsync(item);
                }).GetAwaiter().GetResult();
            }
            return doc;
        }

        public void DeleteJobApp(string id)
        {
            if (!string.IsNullOrEmpty(id))
            {
                Task.Run(async () =>
                {
                    await this.DeleteItemAsync(id);
                }).GetAwaiter().GetResult();
            }

        }

#endif
    }
}

Wednesday, May 13, 2015

C# Using JSON in Web.Config (or any config) file for static object store

This is a short article on how to access static data using JSON in a config file. Hope you find it useful in your project.

I'm going to show you how I use static data to store things like commands, or anything that remains unchanged. This project is based on the Automotive CAN Bus, where there are many messages you can query, thousands, actually. By adding the ones you're interested in, into a static file, you can chose which messages you want to display to the user.

1. Create Your Static JSON Data in your added config file, this one is called CanReceive.Config.








2. Add reference to the added config file to your main config file. Here, Under configSections, section add value for canReceive and then add a section called canReceive with the filename of your configSource.




3. Create a POCO class to represent your JSON Data.


4. Create a Static Config Class to read the data from the config file as a JSON String. CanReceive is the one we are interested in here.
















5. Create a Dictionary Class to store your serialized JSON objects and an ID to get them.




















5. Use your dictionary in Code by calling the methods:

A. CanReceiveSingleton.Instance.GetMapByIdx(0);



There it is, I find this useful in a number of scenarios where I need a way to access a list of data for further processing.

Jonathan