.NET Projects You Should Be Follwing On Github

19. July 2015 04:51

API ASP.NET ASP.NET MVC C# Musings Web 

Open-source has entirely change the programming and developers world. Today you can create any application, game, mobile app without spending a single penny. Thanks to open-source software and awesome community of developers and people behind them. As a .NET developer I have been developing enterprise applications for quite a long time and now I have shifted my focus towards developing products and understanding what it takes to make a successful product launch.

Back then, I used to spend most of my time in investigating the new technologies and what technology we should be using to get this thing done. I still do that today, not because it is the requirement of the project but because I have been asking a lot of questions. The list of projects I have compiled below are the projects that have helped me in learning lots of new things and insights of the programming and I hope this does the same for you as well.  Here is the list of awesome open-source project that you should be following on Github.

Pinta


We all know about Paint.net, it is an awesome tool and a complete replacement of Photoshop (at least for me). And yet there is another project which is almost the same and open-source and it works on Linux and Mac. It uses Gtk# (Gtk sharp) to run on both Window and Linux platforms. This project is a must have if you are a .NET guy and want to get yourself into some serious programming. You will learn about the insights of using gtk# in your projects. Though Microsoft already took the steps to have .NET FX on Linux but still this project is a great learning source.

Official site: http://www.pinta-project.com/

Github: https://github.com/PintaProject/Pinta

 

ShareX


I take a lot of screen shots and record screen casts as well for my personal use. But I used to use two different tools to get the work done. This is one of the tools that will not just take screen shots or just let you record your screen casts easily, it will also allow you to upload them to the 40 different image storing cloud services. Dive into the source code and see the awesomeness under the hood. Here is the project description as seen on Github.

ShareX is an open source program that lets you take screenshots or screencasts of any selected area with a single key, save them in your clipboard, hard disk or instantly upload them to over 40 different file hosting services. In addition to taking screenshots, it can upload images, text files and all other different file types.

Official site: https://getsharex.com/

Github: https://github.com/ShareX/ShareX

 

StackExchange - Data Explorer


You got a programming question, you Google it and it redirects it to StackOverflow. StackOverflow needs no introduction among programmers. StackOverflow is one of the Q&A site dedicated to the developers to get the answers for their problems. But it is just one site. In the recent years StackExchange has grew up and not just providing support for programmers but also helping folks from other fields. Now the data StackExchange has is available for anyone out there for free under creative-commons. If you are interested in looking into the source code that powers the user to query that immense amount of data bank then head over to Github and fork this project. StackExchange is all about Microsoft stack and this tool is also written in ASP.NET MVC3.

Official App: https://data.stackexchange.com/

Github: https://github.com/StackExchange/StackExchange.DataExplorer

 

Mini Blog


This is the minimalistic blog engine written in ASP.NET web pages by the author of BlogEngine.NET, Mads Kristensen. I started my bog with BlogEngine.NET and I had an amazing experience with it. MiniBlog is totally different in terms of features that are offered by BlogEngine.NET. This project will tell you the power of web pages and how you can write your own simple site without wasting much time.

Demo: http://miniblog.azurewebsites.net/ (with user name and password as demo).

Github: https://github.com/madskristensen/MiniBlog

 

Fluent Scheduler

If you want to run cron jobs or automated jobs in your application quietly, then this is the library you should be using. The documentation is pretty sleek and get you started in no time. But other than that you should take a look at the source code and see how nicely this has been done.

Github: https://github.com/jgeurts/FluentScheduler

 

Dapper

A Micro-ORM used by StackExchange sites. This is a perfect replacement for EF. This is just a single file that you can drop in your project and get started.

Dapper is a single file you can drop in to your project that will extend your IDbConnection interface.

Github: https://github.com/StackExchange/dapper-dot-net

 

LINQ-toWIKI

A .NET library to access MediaWiki API. The library is almost 3 years old but the source code will worth the look. Excerpt from Github:

LinqToWiki is a library for accessing sites running MediaWiki (including Wikipedia) through the MediaWiki API from .Net languages like C# and VB.NET.

It can be used to do almost anything that can be done from the web interface and more, including things like editing articles, listing articles in categories, listing all kinds of links on a page and much more. Querying the various lists available can be done using LINQ queries, which then get translated into efficient API requests.

Github: https://github.com/svick/LINQ-to-Wiki

 No Rating

Building Real Time Applications With Firebase And AngularJS

17. May 2014 23:25

API Cloud Web 

Building real-time applications with SignalR is easy. But building real-time applications with JavaScript will be a problem if you are not aware of Firebase. I first heard of it when I was learning AngularJS. The official AngularJS site has the example where you can add, edit and delete the detials in real-time. This example uses Firebase as the storage and updates the UI in real time. 

The data is stored in JSON format and accessing it using jQuery makes it very easy. Firebase API is pretty powerful and lets you get started in minutes. To get started with Firebase, you have to first create a new account with Firebase. It's a paid service but for now you can opt for a developer account. As soon as your account is created you will be redirected to your dashboard where you can create a new application or use the one which is there by default from Firebase. Take the note of the URL ending with firebaseIO.com, we will be needing it later on at the time of implementing.

Clicking on Manage App button will take you to the details page of the application. Where you can view/edit/import/export the data in the JSON format, authentication from Facebook, Twitter, Google etc, simulate read/write operation and more. You can see the sample data in JSON format I have been testing in the below screenshot. If you already have a JSON file, you can directly import it from the dashboard using the Import JSON feature.

For this example I am using jQuery and AngularJS. If you wish you can just stick to jQuery. Create a new HTML page and add Firebase JS references in the head section. I am using AngularJS so I am going to add AngularJS reference as well.

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="https://cdn.firebase.com/js/client/1.0.11/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/0.7.1/angularfire.min.js"></script>

You get the first three references but the last reference is the AngularFire which is a quick way to work with Firebase applications with AngularJS. This is AngularJS code with firebase dependency.

var feedApp = angular.module('feedDataApp', ['firebase']);

feedApp.controller('feedListController', function ($scope, $firebase) {
    var fbURL = new Firebase("https://scorching-fire-0000.firebaseio.com/Feeds/");
    $scope.feedsList = $firebase(fbURL);

    $scope.save = function () {
        $scope.feedsList.$add({
            Name: $scope.feedsList.Name,
            Url: $scope.feedsList.Url,
            Description: $scope.feedsList.Description
            
        });
        $(":text").val('');
    }
});

I am not getting into the basics of AngularJS, but I will explain few things in the above code. The first line in the above code has the dependency named firebase, in simple AngularJS apps we could have skip the dependecies. Then I have the controller named feeListController, which is accompanied by a very own $scope and new param which is $firebase. Inside the controller I have a variable fbURL which holds my Firebase URL. If you see here, you willl notice that I have appended the URL with Feeds. This is because I want my data to be saved inside the Feeds section in the Firebase storage. The $scope.feedsList will hold the collection of all my entries I have in my storage. I have the save function which will save the details to my storage. Inside the Firebase's $add function, I have passed Name, Url and Description. You can pass as many params as you want. the best thing is that you don't even have to set the storage schema. As soon as you click the save button, a new entry is created in the storage. This is my storage looks like.

If you don't want to save it under the Feeds section then in the above JS file you just have to remove the Feeds from the above URL. The UI for this demo is simple, just listing down the saved JSON data in a readable form using AngularJS.

<div ng-controller="feedListController">
    <table class="table">
        <tr>
            <td>
                Name
            </td>
            <td>
                Url
            </td>
            <td>
                Description
            </td>
        </tr>
        <tr ng-repeat=" feeds in feedsList">
            <td>{{feeds.Name}}</td>
            <td>{{feeds.Url}}</td>
            <td>{{feeds.Description}}</td>
        </tr>
        <tr>
            <td>
                <input type="text" ng-model="feedsList.Name" /><br />
            </td>
            <td>
                <input type="text" ng-model="feedsList.Url" /><br />
            </td>
            <td>
                <input type="text" ng-model="feedsList.Description" /><br />
            </td>
            <td>
                <button type="submit" ng-click="save()">Add Feed</button>
            </td>
        </tr>
    </table>
</div>

Using a simple design I have displayed the details using AngularJS.

The best part is the as soon as I add a new feed details, it will get updated in the UI in real-time. Open the same page on a different browser and add a new entry. You will notice that the data is updated in real-time.

Firebase is not limited for web, it is available for iOS/OS x, Java/Android, Node.js, Ember etc. Building mobile applications using Firebase as a real-time storage will be an amazing thing to do. This is not a very good example for Firebase with AngularJS but this will get you started with Firebase and let you test a part of your application using this awesome real-time storage.

I would recommend you to look at this web application build completely on Firebase and AngularJS. 

References

 No Rating

Turn Your Google Drive Folder In An Online Album Viewer

4. May 2014 15:09

API ASP.NET MVC C# Projects Web 

Working with Google Drive API is fun. The documentation is good and will let you get started with the API pretty quickly. I have my whole complete family album on OneDrive, but the API is still a bit hard to use as compared to Google Drive API or maybe it is just for me. But while playing around with Drive API I ended up creating a small razor based web page application which will allow you to show your folder as an online web album. I have the source code at Github.

To get started register your application on the Google Developer Console. Here is a complete guide on how to use the Google APIs.

Copy the API keys and save it on the notepad. The basic usage example on the Google Drive API reference page uses a file called client_secrets.json which actually holds the API key. You can find this file in the bin folder.

{
  "installed": {
    "client_id": "524339914714.apps.googleusercontent.com",
    "client_secret": "_Lq8D_Ai-T2IbhU8m2zXlQa"
  } 
}

You also have to enable the Drive API before you start using it.

I created a wrapper around the Google Drive API so I can use it in my other projects. Here is the complete code of my GoogleDrive class.

using System;
using System.Collections.Generic;
using System.Web;
using Google;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Download;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Logging;
using Google.Apis.Services;
using System.Threading.Tasks;
using System.Threading;
//using Google.Apis.Upload;

public class GoogleDrive
{
    DriveService service = null;
    public GoogleDrive()
    {
        Run().Wait();
    }


    private File GetFileByID(string fileID, DriveService service)
    {
        File file = service.Files.Get(fileID).Execute();
        if (file.ExplicitlyTrashed == null)
            return file;
        return null;
    }

    public string GetFolderID(string FolderName)
    {
        FilesResource.ListRequest request = service.Files.List();
        request.Q = "title = '" + FolderName + "'";
        FileList files = request.Execute();
        return files.Items[0].Id;
    }
    public List<File> ListFolderContent(string FolderID)
    {
        ChildrenResource.ListRequest request = service.Children.List(FolderID);
        List<File> files = new List<File>();
        //request.Q = "mimeType = 'image/jpeg'";

        request.Q = "'" + FolderID + "' in parents";

        do
        {
            try
            {
                ChildList children = request.Execute();

                foreach (ChildReference child in children.Items)
                {
                    files.Add(GetFileByID(child.Id, service));
                }

                request.PageToken = children.NextPageToken;

            }
            catch (Exception e)
            {
                request.PageToken = null;
            }
        } while (!String.IsNullOrEmpty(request.PageToken));
        return files;
    }

    public List<File> ListRootFileFolders()
    {
        List<File> result = new List<File>();
        FilesResource.ListRequest request = service.Files.List();
        do
        {
            try
            {
                FileList files = request.Execute();

                result.AddRange(files.Items);
                request.PageToken = files.NextPageToken;
            }
            catch (Exception e)
            {
                request.PageToken = null;
            }
        } while (!String.IsNullOrEmpty(request.PageToken));
        return result;
    }

    public byte[] DownloadFile(string fileID)
    {
        File file = service.Files.Get(fileID).Execute();
        var bytes = service.HttpClient.GetByteArrayAsync(file.DownloadUrl);
        return  bytes.Result;
    }


    private async Task Run()
    {
        try
        {
            GoogleWebAuthorizationBroker.Folder = "Files";
            UserCredential credential;
            using (var stream = new System.IO.FileStream("client_secrets.json",
                System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets, DriveConstants.Scopes, "user", CancellationToken.None);
            }

            var drvService = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Drive API Sample",

            });

            if (drvService != null)
            {
                service = drvService;
            }
        }
        catch { }
    }
}

The Storage class uses Biggy for the document storage. You have to manually add the names of the folder (considered as albums) on settings page. This will get added/appended in settings.json file in the Data folder which is in the web root of DriveGallery. Here is my settings file.

{"AlbumName":"Atlassian"}
{"AlbumName":"DivX"}
{"AlbumName":"Envato"}
{"AlbumName":"Disqus"}

Settings page from where I can add the names of folders/albums. No view and delete options as of now, but I will soon add it.

The added albums will be listed on the main/default page. The user will then have to click the name of the album to view the contents which should only images. At the moment there is no check which prevents it to show other files rather than only image files.

Google Drive is slow when it comes to handle high amount of data. Google Drive storage is not like Azure or Amazon storage. It’s different and will not get you large results in appropriate time. If you want to use Drive Gallery make sure that you don’t use more than 25-50 images in a folder. Querying 25-50 files in a single go will be long but not more than if you have more than 50. Better option is to break your folder in parts like volume I & II or Part 1 or 2.

I will try to make it look more attractive but for the moment it solves the purpose for me. Click on the View button to view the album. The View page accepts a query string name, which has the name of the folder/album. Google Drive API does not understand the name of the folder, so I have to get the folder id from the name. I will use the GetFolderID method of the GoogleDrive class which gives me the folder id. The received folder id is then passed to ListFolderContent method which will list all the files in the folder.

Please note that, for the moment there is no check to retrieve only images from the folder. GoogleDrive.cs class is a generic version of the class I am using in my other projects. You just need to be sure that you have only images in the folder and not any other file.

Click the View button to view the full size image in the browser else click the Download button to download it directly. Basically Drive API does not have any property which holds the value of the URL to view the image online. So I tweaked the thumbnail URL in the ViewURL property so I can view the images online without having to download it.

public class Albums
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string AlbumName { get; set; }
    public string DownloadURL { get; set; }
    public string ViewURL
    {
        get
        {
            return ThumbnailLink.Replace("=s220", "=s4000");
        }
    }
    public string ThumbnailLink { get; set; }
}

Taking the ThumbnailLink property and replace the =s220 to =s4000 does the trick.

Note: The URLs are not permanent, it will change when the request expires.

Properties of the Album class:

  • Id: File/Image id.
  • Tilte: Title of the image/file.
  • AlbumName: Name of the album/folder.
  • DownloadURL: Download URL of the image/file. Original Drive API property name: DownloadUrl.
  • ViewURL: URL which allows user to view the image in the browser.
  • ThumbnailLink: URL of the thumbnail image. Original Drive API property name: ThumbnailLink.

The duration of the operation depends on the amount of images you have in your folder. The lesser the number of images the fast the query will get executed. Here just for fun I have used Biggy JSON store to save the content details of the folder. If you want to remove it from your implementation, please do so. You may have to change some functions in order to get all other things working fine.

You can download the complete source code from Github. I am still working on it to make it more flexible and good looking. As I am not a designer and I seriously lack when it comes to web designs. Thanks to Twitter bootstrap to make it look a bit good.

Currently rated 5.0 by 1 person

JSON Based Document Storage Using Biggy In ASP.NET MVC

3. May 2014 13:51

API ASP.NET MVC C# Web 

While working with a small web based project many developers will take advantage of web.config and XML files to read settings for the application. Using web.config is a good way but you cannot change the settings from within the application and when done manually it causes the website to restart. XML is good but many of us has a problem when it comes to update the details in XML. Biggy is an awesome library developed by Rob Conery to work with document storage. It does a lot well more than you can think of if you are not following the project closely on Github. For now I am just going to show you how you can use Biggy to save your application data in JSON based document storage. 

The library is not available on NuGet, so you have to download or fork the whole solution from Github and then build it. Create a new MVC application and add the reference of the Biggy assemblies you just build. 

Remove Newtonsoft.Json assembly that is added in your project by default when it is created by Visual Studio. The version of assembly seems to be incompatible with Biggy. Instead use the one which accompanies Biggy. 

Add a new model in your application and name it settings. The settings may depend on your application, as I am using it for my blog I have settings like blog name, blog description, posts per page and disable comments after 'x' days. 

public class Settings
{
    public string BlogName { get; set; }
    public string BlogDescription { get; set; }
    public string PostsPerPage { get; set; }
    public string CommentDays { get; set; }
}
I am manually building my view but you can use scaffolding if you wish to save your time. On submit of the form, the details will be sent to the server where my controller method will save the settings in the JSON file. Here is my view and controller code.
@model BiggyJSONDataStore.Models.Settings
@{
    ViewBag.Title = "Settings Page";
   }

<div class="row">
    @using (Html.BeginForm("Settings", "Home", FormMethod.Post))
    {
        <label>Blog Name</label>
        @Html.TextBoxFor(m => m.BlogName, new { @id = "blogname" })
        <br />
        <label>Blog Description</label>
        @Html.TextBoxFor(m => m.BlogDescription, new { @id = "blogdesc" })
        <br />
        <label>Posts per Page</label>
        @Html.TextBoxFor(m => m.PostsPerPage, new { @id = "postsperpage" })
        <br />
        <label>Disable comments after</label>
        @Html.TextBoxFor(m => m.CommentDays, new { @id = "commentdays" })
        <label>days</label><br />
        <input id="btnSave" type="submit" value="Save Settings" />
    }
</div>
When the first time the page is loaded I want to check if there are settings in the file or not. If settings are there then render my view with settings. So the default GET view will look like this.
IBiggyStore<Settings> settingStore = new JsonStore<Settings>(dbPath: HttpRuntime.AppDomainAppPath);
try
{
    var data = settingStore.Load().Single();
    return View(data);
}
catch { }

return View();
The settingStore object is being created and creates a new file in the Data folder in the application root. the dbPath parameter specifies where the file (JSON file in this case) is saved, which is the web root. The Load() method of the settingStore will load all the data in the JSOn file. In this case I have only single set of setting so I will use the Single() method to get the single setting record and not IEnumerable<Settings>.
IBiggyStore<Settings> settingStore = new JsonStore<Settings>(dbPath: HttpRuntime.AppDomainAppPath);

var store = new BiggyList<Settings>(settingStore);

var newSettings = new Settings();

newSettings.BlogName = setting.BlogName;
newSettings.BlogDescription = setting.BlogDescription;
newSettings.PostsPerPage = setting.PostsPerPage;
newSettings.CommentDays = setting.CommentDays;

store.Add(newSettings);
store.Update(setting);

return View();
The above code will add a new settings to the JSON file.
{"BlogName":"Midnight Programmer","BlogDescription":"Programming For Fun","PostsPerPage":"10","CommentDays":"90"}

At this point if you keep pressing save button by entering different values a new entry will be added to the JSON file. To avoid this you have to update the details instead of adding it over and over again in the JSON file.

IBiggyStore<Settings> settingStore = new JsonStore<Settings>(dbPath: HttpRuntime.AppDomainAppPath);

var store = new BiggyList<Settings>(settingStore);

var newSettings = new Settings();

Settings data = null;
try
{
    data = settingStore.Load().Single();
}
catch { }


if (data != null)
{
    data.BlogName = setting.BlogName;
    data.BlogDescription = setting.BlogDescription;
    data.PostsPerPage = setting.PostsPerPage;
    data.CommentDays = setting.CommentDays;
    store.Update(data);
}
else
{
    newSettings.BlogName = setting.BlogName;
    newSettings.BlogDescription = setting.BlogDescription;
    newSettings.PostsPerPage = setting.PostsPerPage;
    newSettings.CommentDays = setting.CommentDays;
    store.Add(newSettings);
    store.Update(setting);
}

return View();

As you can see that the store object Add method is not called but only the Update method is called in case if the data object is not null.  

If you plan to save multiple records in the file, then make sure you use identifier in order to get the required details.

References:

Biggy - Github

Currently rated 5.0 by 1 person

Building MVC Application With Multiple Database Support Using Ninject

13. May 2013 14:33

API ASP.NET MVC C# 

I used to have BlogEngine.NET as my blogging platform before switching to WordPress, and that is because of my poor hosting provider who can’t afford few MBs on the shared hosting plans. I like BlogEngine.NET a lot because it is in .NET and on the other hand WordPress is on PHP which I don’t know. BlogEngine.NET is still evolving and is getting better with every release. BlogEngine.NET supports multiple databases like SQL Server, SQL Server CE, MySQL, XML file, VistaDB and may be few more. As it is open-source, I jumped into the code and found it to be a bit hard to get through its implementation. To be frank, I didn’t look into that deep!! but it is not implementing what I was expecting it was. What I was expecting was the use of dependency injection (DI).

I am constantly working on new projects open-source and freelanced and few of them are for fun. The application I am working on right now requires a multiple DB support. The main problem I am going to face is not writing different functions for different DB operations, but having them integrated at the time when the user selects the database. BlogEngine.NET implements it pretty impressively, but I was expecting something else. For my project I will be using Ninject. If you want to do for your application, then this is how you can do it.

Create a new MVC internet application. First thing that we need to do is to add Ninject reference to the project by firing the below Nuget command. Remember that for MVC application you need to use Ninject.MVC3 and for other applications you need to use Ninject only: Install-Package Ninject

Install-Package Ninject.MVC3

When the library is installed successfully, you will notice a file under App_Start folder named NinjectWebCommon.cs. This is a very important file and we will look into it this later when we are done with other things.

What I am trying to achieve here is that my application would be able to support multiple databases and I also want to keep my code clean. I don’t want to handle it using some if..else conditions. Ninject does the work for me pretty well here. I will create an interface that will have all the functions which my wrapper classes will implement. For the sake of simplicity for this example I am going to perform basis CRUD operations, I will be writing code to implement two database support and will be using a custom written ORM called Dapper to communicate to the DB (you can use EF if you wish). I will name my interface IDBProvider.

public interface IDBProvider
{
    bool Add(Friends friend);
    bool Update(int Id, Friends friend);
    bool Delete(int Id);
    IEnumerable ListFriends();
    Friends ListFriend(int Id);
}

As you can see from the above code that I am using Friends model to save details of my friend. So here is my model.

public class Friends
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Skype { get; set; }
}

After this I am going to have support for two databases, SQL Server and SQL Server CE (4.0). For this I will create 2 classes which will implement the IDBProvider interface naming SQLHelper.cs and SQLCEHelper.cs respectively.

SQLHelper.cs

public class SQLHelper : IDBProvider
{
    string ConStr = ConfigurationManager.ConnectionStrings["Con"].ConnectionString;
 
    public bool Add(Friends friend)
    {
        bool Added = false;
 
        try
        {
            using (SqlConnection con = new SqlConnection(ConStr))
            {
                string insertSQL = "INSERT INTO Friends(Name, Email, Skype) VALUES (@Name, @Email, @Skype)";
                con.Open();
                con.Execute(insertSQL, new
                {
                    friend.Name,
                    friend.Email,
                    friend.Skype
                });
 
                Added = true;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
 
        return Added;
    }
 
    public IEnumerable ListFriends()
    {
        try
        {
            using (SqlConnection con = new SqlConnection(ConStr))
            {
                string strQuery = "Select Id, Name, Email, Skype FROM Friends";
                con.Open();
                var AllFriends = con.Query(strQuery);
 
                return AllFriends;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
    }
 
    public Friends ListFriend(int Id)
    {
        try
        {
            using (SqlConnection con = new SqlConnection(ConStr))
            {
                string strQuery = "SELECT Id, Name, Email, Skype FROM Friends WHERE Id=" + Id;
                con.Open();
                var friend = con.Query(strQuery).Single();
                return friend;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
    }
 
    public bool Update(int Id, Friends friend)
    {
        bool Update = false;
        try
        {
            using (SqlConnection con = new SqlConnection(ConStr))
            {
                string strUpdate = "UPDATE Friends SET Name = @Name, Email = @Email, Skype = @Skype WHERE Id = " + Id;
                con.Open();
                con.Execute(strUpdate, new
                {
                    friend.Name,
                    friend.Email,
                    friend.Skype
                });
 
                Update = true;
            }
 
        }
        catch (Exception x)
        {
            throw x;
        }
 
        return Update;
    }
 
    public bool Delete(int Id)
    {
        bool Deleted = false;
        try
        {
            using (SqlConnection con = new SqlConnection(ConStr))
            {
                string strDelete = "DELETE FROM Friends WHERE Id = " + Id;
                con.Open();
                int i = con.Execute(strDelete);
                if (i > 0)
                    Deleted = true;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
 
        return Deleted;
    }
}

SQLCEHelper.cs

public class SQLCEHelper : IDBProvider
{
    string ConStr = ConfigurationManager.ConnectionStrings["Con"].ConnectionString;
 
    public bool Add(Friends friend)
    {
        bool Added = false;
 
        try
        {
            using (SqlCeConnection con = new SqlCeConnection(ConStr))
            {
                string insertSQL = "INSERT INTO Friends(Name, Email, Skype) VALUES (@Name, @Email, @Skype)";
                con.Open();
                con.Execute(insertSQL, new
                {
                    friend.Name,
                    friend.Email,
                    friend.Skype
                });
 
                Added = true;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
 
        return Added;
 
    }
 
    public bool Update(int Id, Friends friend)
    {
        bool Update = false;
        try
        {
            using (SqlCeConnection con = new SqlCeConnection(ConStr))
            {
                string strUpdate = "UPDATE Friends SET Name = @Name, Email = @Email, Skype = @Skype WHERE Id = "+Id;
                con.Open();
                con.Execute(strUpdate, new
                {
                    friend.Name,
                    friend.Email,
                    friend.Skype
                });
 
                Update = true;
            }
 
        }
        catch (Exception x)
        {
            throw x;
        }
 
        return Update;
    }
 
    public bool Delete(int Id)
    {
         bool Deleted = false;
         try
         {
             using (SqlCeConnection con = new SqlCeConnection(ConStr))
             {
                 string strDelete = "DELETE FROM Friends WHERE Id = " + Id;
                 con.Open();
                 int i = con.Execute(strDelete);
                 if (i > 0)
                     Deleted = true;
             }
         }
         catch (Exception x)
         {
             throw x;
         }
 
         return Deleted;
    }
 
    public IEnumerable ListFriends()
    {
        try
        {
            using (SqlCeConnection con = new SqlCeConnection(ConStr))
            {
                string strQuery = "Select Id, Name, Email, Skype FROM Friends";
                con.Open();
                var AllFriends = con.Query(strQuery);
 
                return AllFriends;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
    }
 
    public Friends ListFriend(int Id)
    {
        try
        {
            using (SqlCeConnection con = new SqlCeConnection(ConStr))
            {
                string strQuery = "SELECT Id, Name, Email, Skype FROM Friends WHERE Id=" + Id;
                con.Open();
                var friend = con.Query(strQuery).Single();
                return friend;
            }
        }
        catch (Exception x)
        {
            throw x;
        }
    }
}

The question now here is that how would the application will know which DB to use as a data store? For this I made few settings in my web.config file. In the appSettings section I added a setting that will hold the value which we use as an identifier and connect to the DB. You can have different approach to achieve this, it is not at all necessary to use what I have used here. My app setting in web.config looks something like this:

<add key="DBProvider" value="SQL"/>

When reading this settings I will be dynamically calling or injecting the code on the basis of the value of DBProvider in my app settings. In this case I will bind SQLHelper when the value is SQL and SQLCEHelper when the value is SQLCE. In the start of the tutorial I mentioned about the NinjectWebCommon.cs file in the App_Start folder. Here we will be looking into CreateKernel method as this is the place where I implement my helper classes.

private static IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
    kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
 
    if (ConfigurationManager.AppSettings["DBProvider"].ToString().ToLower() == "sql")
    {
        kernel.Bind<IDBProvider>().To<SQLHelper>();
    }
    else
    {
        kernel.Bind<IDBProvider>().To<SQLCEHelper>();
    }
 
    RegisterServices(kernel);
    return kernel;
}

Notice the highlighted code. I am conditionally binding the implementation on the basis of the settings in my web.config file. What exactly is happening here is that the code is being injected depending on the conditions and this is why we call it dependency injection.

To get the benefit of this, we need to make few changes to our controller.

private readonly IDBProvider _dbProvider;
 
public HomeController(IDBProvider dbProvider)
{
    this._dbProvider = dbProvider;
}

I have a default constructor which takes the IDBProvider as a parameter. The IDBProvider object is all we need which provides us all its implementation. To add a friend to DB you just have to call the Add method like _dbProvider.Add(friend). Same for edit, update, delete and list all the friends. You noticed that no where in the code I have made use of the SQLHelper.cs or SQLCEHelper.cs classes. This is the awesomeness of DI.

This is all it and now your application is flexible enough to use multiple databases. I strongly recommend you to read the documentation on Ninject at Ninject.org as it is vast and can be a life saver in many scenarios.

 No Rating