Monday, November 4, 2013

New Big Data Projects

Some interesting big data related projects.

  • Databus - Databus provides a timeline-consistent stream of change capture events for a database. Github link.
  • Samza - Apache Samza is a distributed stream processing framework. It uses Apache Kafka for messaging, and Apache Hadoop YARN to provide fault tolerance, processor isolation, security, and resource management.
  • Druid - Druid is open source infrastructure for Real²time Exploratory Analytics on Large Datasets. The system uses an always-on, distributed, shared-nothing, architecture designed for real-time querying and data ingestion. It leverages column-orientation and advanced indexing structures to allow for cost effective, arbitrary exploration of multi-billion-row tables with sub-second latencies.
  • Grape - Grape is a realtime processing pipeline.

Sunday, November 3, 2013

Building Booky SPA - Building a RESTFul API for Booky using ASP.NET Web API

REST stands for Representational State Transfer.
  • REST is an architectural style that runs over HTTP. 
  • REST is used for exchanging data over HTTP. 
  • REST is simple and stateless
  • REST is not an official protocol or standard.

The core idea behind the creation of REST based services is that we should treat our distributed services as a resource and we should be able to use simple HTTP verbs to perform various operations on that resource.


In booky we have the following resources:
  • users
  • bookmarks
  • boards - not implemented
  • tags - not implemented

Each resource is available from a URI. booky REST URI's is created with the following URI http://domain.tld/rest/. Each booky resource will take on a URI such as:
  • users - http://domain.tld/rest/user
  • bookmarks - http://domain.tld/rest/bookmark
  • boards - http://domain.tld/rest/board
  • tags - http://domain.tld/rest/tag

In cases where REST-ful style doesn't fit with the application requirements, a REST-hybrid URI design can be used, such as with server side paging and application design

In booky a REST-hybrid URI http://domain.tld/actions is created so that there is an area for REST only URI's and REST-hybrid URI's. 
  • http://domain.tld/rest/ -  booky common REST URI's
  • http://domain.tld/actions/ - booky common REST-hybrid URI's

Example - booky common REST-hybrid URI's:
  • Server side paged bookmarks - http://domain.tld/actions/bookmarkaction/GetPagedBookmarks/
  • Updating a single bookmark property/attribute that indicates whether a bookmark has been read. - http://domain.tld/actions/bookmarkaction/toggleread/

HTTP Verbs

On the server each server side operation (Create, Read, Update, DELETE) maps to an HTTP verb:
  • GET  
  • POST 
  • PUT 
  • DELETE 
GET

Gets a listing of resources. When no resource id is specified then all resources are returned. When a resource id is specified then a single resource is returned. 

Example: 

  • GET http://domain.tld/rest/bookmark/1 - single resource 
  • GET http://domain.tld/rest/bookmark - listing of resources

POST

Creates a new resource. On successful creation, return HTTP status 201, returning a Location header with a link to the newly-created resource with the 201 HTTP status.When the resource can't be found return a 404 not found HTTP Response Code. POST is neither safe nor idempotent. It is therefore recommended for non-idempotent resource requests. Making two identical POST requests will most-likely result in two resources containing the same information.

Example: 
  • POST http://domain.tld/rest/bookmark

PUT

Updates an existing resource. On successful update, return HTTP status 200, returning a Location header with a link to the updated resource with the 201 HTTP status.When the resource can't be found return a 404 not found HTTP Response Code.

Example: 

  • PUT http://domain.tld/rest/bookmark/1 

DELETE

- Deletes an existing resource.  On successful delete, return HTTP status 200, and in the response body the representation of the deleted item.

Example: 

  • DELETE http://domain.tld/rest/bookmark/1

HTTP Response Codes for use in response headers

The listing below outlines the typical HTTP Response Code to use for each server operation/HTTP verb combo:
  • GET - 200 OK
  • POST -  201 Created 
  • PUT - 200 OK
  • DELETE - 200 OK
A standard that I follow for PUT/DELETE/GET is when the resource can't be found is to return a 404 not found HTTP Response Code.

A listing HTTP Response Codes for reference:
  • 200 OK: Success
  • 201 Created - Used on POST request when creating a new resource.
  • 304 Not Modified: no new data to return.
  • 400 Bad Request: Invalid Request.
  • 401 Unauthorized: Authentication.
  • 403 Forbidden: Authorization
  • 404 Not Found – entity does not exist.
  • 406 Not Acceptable – bad params.
  • 409 Conflict - For POST / PUT requests if the resource already exists.
  • 500 Internal Server Error
  • 503 Service Unavailable

Additional resources that provide expanded HTTP Response Codes information:

REST was introduced and defined by Roy Fielding in 2000.


This completes an overview on REST basics. ASP.NET Web API is up next followed by booky ASP.NET Web API Design.

What is ASP.NET Web API?

ASP.NET Web API is a framework for building and consuming HTTP services that can reach a broad range of clients including browsers, phones and tablets. You can use XML or JSON or something else with your API. JSON is nice for mobile apps with slow connections, for example. You can call an API from jQuery and better utilize the client's machine and browser.

Why use ASP.NET Web API?

ASP.NET Web API provides the following benefits: 

  • From a focus standpoint MS Web API doesn't try to be all things; Web API is designed and focuses on HTTP
  • Easier to secure than other ASP.NET web service options (WCF, ASMX)
  • Has close integration of MS Web API with ASP.NET MVC; Uses the controller (Controller class) model found in ASP.NET MVC which developers may already be familiar with.

booky ASP.NET API Design

booky contains the following ASP.NET Web API controllers for each REST resource.

booky Controller Classes for Common REST URI's:

  • Bookmark resource - BookmarkController Class - Get Bookmark 
  • User resource - UserController Class - Update User (PUT)

booky Controller Classes for Common REST-hybird URI's:

  • User Action Controller - Authenticate user and Register user
  • Bookmark Action Controller - Get Paged Bookmarks, Get Bookmark By Url, Toggle Favorite, Toggle Read.

Bonus: CORS

CORS - Cross Origin Resource Sharing

Implementation of CORS via Web.config

<system.webServer>
 <httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
 </httpProtocol>
</system.webServer>


<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <remove name="WebDAVModule"/>
  </modules>
  <handlers>
    <remove name="WebDAV" />
  </handlers>
</system.webServer>

You can also implement CORS via code by creating a Message Handler:

In Global.asax add the CorsHandler.

GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());

 public class CorsHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    return Task.Factory.StartNew(() =>
                    {
                        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                        response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                        string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                        if (accessControlRequestMethod != null)
                        {
                            response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                        }

                        string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                        if (!string.IsNullOrEmpty(requestedHeaders))
                        {
                            response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                        }

                        return response;
                    }, cancellationToken);
                }
                else
                {
                    return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }




Build 2015 - Service Fabric

One exciting announcement from Build this year was that of Service Fabric.
What can you do with Service Fabric?
Build and operate always-on, hyper-scale services using the same technology powering Microsoft’s Cloud.
Overview
Service Fabric is a distributed systems platform used to build scalable, reliable, and easily-managed applications for the cloud. Service Fabric addresses the significant challenges in developing and managing cloud applications. By using Service Fabric developers and administrators can avoid solving complex infrastructure problems and focus instead on implementing mission critical, demanding workloads knowing that they are scalable, reliable, and manageable. Service Fabric represents the next-generation middleware platform for building and managing these enterprise class, Tier-1 cloud scale services.

Service Fabric enables you to build and manage scalable and reliable applications composed of microservices running at very high density on a shared pool of machines (commonly referred to as a Service Fabric cluster). It provides a sophisticated runtime for building distributed, scalable stateless and stateful microservices and comprehensive application management capabilities for provisioning, deploying, monitoring, upgrading/patching, and deleting deployed applications.
Service Fabric powers many Microsoft services today such as Azure SQL Databases, Azure DocumentDB, Cortana, Power BI, Intune, Azure Event Hubs, many core Azure Services, and Skype for Business to name a few.
Where can you run Service Fabric?
On Azure and on premise
More information
Link - aka.ms/servicefabric
Windows Build Video - skip to 30:13 in - http://channel9.msdn.com/Events/Build/2015/3-618

Wednesday, October 30, 2013

Textarea Max Length Directive Sample for all browsers plus IE9

Here is a text area max length Angular Directive that will stop user text input upon reaching the max length specified:

http://plnkr.co/edit/59d3i8?p=preview

Sunday, October 27, 2013

Building Booky SPA - A quick tour of AngularJS and Booky Angular Design


In this post I give a quick tour of AngularJS concepts and touch on some of the AngularJS Design for Booky.

What is AngularJS?

"AngularJS is a new, powerful, client-side technology that provides a way of accomplishing really powerful things in a way that embraces and extends HTML, CSS and JavaScript, while shoring up some of its glaring deficiencies. It is what HTML would have been, had it been built for dynamic content." - Reference

Two way Data Binding

Besides being the coolest feature to come out of AngularJS, two way data binding provides us with:

  • Any changes to the view update the model
  • Any changes to the model update the view


Time saving benefits:

  • Saves us from writing boiler plate code that is typically written to traverse, manipulate and listing to the DOM.


Two Way Data Binding Plunker Sample

Model

In AngularJS, the model contains plain old javascript objects such as string, booleans, arrays that represent the objects viewable in the view and those which are manipulated in AngularJS controller. The model is contained in AngularJS scope.

View

In AngularJS, the view is the HTML that is rendered after AngularJS has parsed and compiled the HTML to include rendered markup and bindings.

Controller

In AngularJS, a Controller is the glue between an the view and model. A controller contains the business logic for the view. For example, if you had search form with a search box and search button, you could have a function in your controller that handles executing a call to a search service each time the search button is clicked.

There is one cardinal rule with an AngularJS Controller:

- The controller does not manipulate the DOM. Directives should be created to manipulate the DOM.

Controller Plunker Sample

Filters

In AngularJS, Filters allow us to format data in some way. For example, a built in Filter from AngularJS called uppercase would make all characters UPPERCASE. Filters cleanup our HTML code by removing the formatting from the view. A filter is created in AngularJS Module much like the other AngularJS concepts such as controllers, directives, etc.

Filter Plunker Sample

Boolean Yes/No Custom Filter Plunker Sample

Directives

AngularJS Directives are the core functions that get run when the DOM is compiled by the AngularJS compiler.

In AngularJS, Directives allow us to build reusable UI components by creating new directives that encapsulate the different application UI aspects such as logo, navigation, etc. With this concept each Directive encapsulate a single UI component, and provide simple DOM manipulation that modify or even create totally new behavior in HTML.

Custom Directive Plunker Sample

Modules

In AngularJS, Modules are the main way to define our AngularJS app. Each application can have multiple modules.

There are different modules in an app such as:
main app module
controller module
directive module
filter module
service module

We logically organize each area of the app into a module. For example, we create a module for controllers and all individual controllers go in the controller module.

Booky AngularJS Design

  • booky has the following modules:
  • booky app module - booky main ng-app 
  • booky filter module - booky.filters - contains all Angular filters
  • book directive module - booky.directives - contains all Angular directives
  • booky controller module - booky.controllers - contains all Angular controllers
  • booky authentication factory - authservice - Angular factory for communicating
  • booky restservice - Angular factory for communicating with booky WebAPI REST service
  • booky bkyviewmodel - Angular factory that is a layer of abstraction between the booky viewmodel and booky server side MS Web API REST service. All booky controllers work with the bky viewmodel factory rather than directly communicating with the booky restservice.
  • booky scrnur rest factory - scrnurservice - Screen Shot service for communicating with Scrnur

Saturday, October 5, 2013

An Angular Select directive with multiple selection support that works in IE8 or greater, FireFox and Chrome.


Here is an Angular select directive that has multiple selection support and it works in IE 8 or greater, FireFox and Chrome.

directives.directive('multiselect', function () {
    return {
        restrict: 'A',    // Restricted to an attribute
        scope:
            {
                enableAll: '=',
                options: '=', // Two data binding. Value, DisplayValue, selected
                onSelected: '&' // function called onSelected
            },
        template:
        '<div style="display: inline-block;">' +
        '<span ng-click="showOptions=!showOptions" class="ui-dropdownchecklist ui-dropdownchecklist-selector-wrapper ui-widget" style="display: inline-block; cursor: default; overflow: hidden;">' +
        '   <span class="ui-dropdownchecklist-selector ui-state-default" tabindex="0" style="display: block; overflow: hidden; white-space: nowrap;">'+
        '       <span class="ui-dropdownchecklist-text" style="display: block; white-space: nowrap; overflow: hidden;">{{displayItems}}</span>' +

        '   </span>' +
        '</span>' +
        '<div ng-show="showOptions" class="ui-dropdownchecklist ui-dropdownchecklist-dropcontainer-wrapper ui-widget" style="position: absolute; height: 150px; width: auto; min-width: 227px; z-index: 401;">'+
        '   <div class="ui-dropdownchecklist-dropcontainer ui-widget-content" style="overflow-y: auto; height: 150px;">'+
     
        // All
        '       <div ng-show="enableAll" class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">' +
        '           <input type="checkbox" ng-change="selectAll(allSelected)" class="active" index="0" value="0" ng-model="allSelected"><label class="ui-dropdownchecklist-text" title="All" style="cursor: default;">All</label>' +
        '       </div>' +  

        '       <div ng-repeat="item in options" class="ui-dropdownchecklist-item ui-state-default" style="white-space: nowrap;">' +
        '           <input type="checkbox" ng-model="item.selected" class="active" index="{{$index+1}}" ng-change="itemChecked()" ><label class="ui-dropdownchecklist-text" title="{{item.DisplayName}}" style="cursor: default;">{{item.DisplayName}}</label>' +
        '       </div>'+      
        '   </div>'+  
        ' </div>'+  
        ' </div>',
        controller: ['$scope', function ($scope) {

            $scope.selectAll = function (item) {
                angular.forEach($scope.options, function (value) {
                    value.selected = item;
                });

                $scope.hasChecked = item;
            };

            $scope.itemChecked = function () {
                $scope.allSelected = true;
                $scope.hasChecked = false;

                angular.forEach($scope.options, function (value) {
                    $scope.allSelected = value.selected && $scope.allSelected;
                    $scope.hasChecked = value.selected || $scope.hasChecked;
                });
            };

            $scope.$watch('options', function(options) {

                if (options) {
                    var listItemsChecked = _.filter(options, function (item) {
                        return item.selected;
                    });

                    if (listItemsChecked) {
                        // Create a list of display items
                        var listOfDisplayItems = _.pluck(listItemsChecked, 'DisplayName');
                     
                        $scope.displayItems = listOfDisplayItems.join();
                    }
                }
            },true);
        }
        ]
};
});

The Angular controller to provide supporting array could look like this:

testApp.controller('MulipleSelectTestController', function ($scope) {
 
    $scope.selectListItems = [
        { Value: 1, DisplayName: 'Kansas', selected: true},
        { Value: 2, DisplayName: 'Ohio' },
        { Value: 3, DisplayName: 'New York' },
    ];

Required CSS:

.ui-dropdownchecklist { width: 228px; }
.ui-dropdownchecklist .ui-dropdownchecklist-selector { background: #fff url('../Images/dropdown.png') no-repeat right center; border: 1px solid #ddd; border-right: 0; height: 20px; text-align: left; }
.ui-dropdownchecklist .ui-dropdownchecklist-selector.ui-state-hover, .ui-dropdownchecklist .ui-dropdownchecklist-selector.ui-state-active { background-image: url('../Images/dropdown_hover.png'); border-color: #5794bf; }

.ui-dropdownchecklist-text, .ui-dropdownchecklist-item { font-family: Arial; font-size: 13px; }
.ui-dropdownchecklist-text { font-weight: 400; height: 20px; line-height: 20px; margin-right:18px; padding-left: 4px; }

.ui-dropdownchecklist-dropcontainer-wrapper { width: auto; z-index: 405 !important; }
.ui-dropdownchecklist-dropcontainer { overflow: hidden; }
.ui-dropdownchecklist-group { font-style: italic; font-weight: 700; }
.ui-dropdownchecklist-item.ui-dropdownchecklist-indent { padding-left: 20px; }

.ui-state-default.ui-dropdownchecklist-selector, .ui-state-hover.ui-dropdownchecklist-selector { color: #000; }
.ui-widget-content.ui-dropdownchecklist-dropcontainer { background: #fff; border: 1px solid #999; }
.ui-widget-content .ui-state-default.ui-dropdownchecklist-item { background: #fff; border: 0; color: #000; }
.ui-widget-content .ui-state-hover.ui-dropdownchecklist-item { background: #39f; border: 0; color: #fff; }

Monday, September 2, 2013

XMLHttpRequest - For reference

XmlHttpRequest Reference code

var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();

Thursday, August 22, 2013

Building Booky SPA - Building Booky Entity Framework Code First

The main steps to building Entity Framework Code First is to:

  1. Create POCO model classes 
  2. Create a derived type that inherits from DbContext which includes DbSet properties 

(System.Data.Entity.DbSet<TEntity>) for each POCO model class, and optionally override the methods we want to customize to create our own DbContext implementation. We will use the domain model from booky. Booky has the concept of Bookmarks, Tags, Users and Boards.

Creating a Domain Model

Booky requires the following relationships based on how the data is best modeled. Booky has the concept of a user where each User has one to many Bookmarks. This is written as One User to many Bookmarks (one to many). Booky has the concepts of Boards which are like groups that allow you to group a list of Bookmarks that are associated with a Board. Booky has one Board to many Bookmarks which is written as One Board to many Bookmarks (one to many). Booky has the concept of each Bookmark being assigned many Tags which are shared among all Bookmarks. Booky has a Many to Many relationship between Tags and Bookmarks (Many to Many).

Booky Code First Class Diagram



Let's review a code example of the booky domain model.

Bookmark POCO Sample:

 public class Bookmark  
 {  
   #region Fields  
   [Key]  
   public int BookmarkId { get; set; }  
   [Required, MaxLength(128)]  
    public string Title { get; set; }  
   [Required, MaxLength(512)]  
   public string Url { get; set; }  
   public DateTime DtCreated { get; set; }  
   public bool Read { get; set; }  
   public bool Starred { get; set; }  
   [Required, MaxLength(128)]  
   public string Description { get; set; }  
   public int UserId { get; set; }  
   public User User { get; set; }  
   public virtual ICollection<Tag> Tags { get; set; }  
   public Board Board { get; set; }  
   #endregion  
   #region ctor  
   public Bookmark()  
   {  
     Tags = new HashSet<Tag>();  
   }  
   #endregion  
 }  

User POCO Sample:

 public class User  
 {  
   [Key]  
   public int UserId { get; set; }  
   [Required, MaxLength(16)]  
   public string Username { get; set; }  
   [Required]  
   public string PasswordHash { get; set; }  
   [Required, MaxLength(256)]  
   public string Email { get; set; }  
   public DateTime DtCreated { get; set; }  
   public DateTime? DtLastUpdated { get; set; }  
   public virtual ICollection<Bookmark> Bookmarks { get; set; }  
   public User()  
   {   
     Bookmarks = new HashSet<Bookmark>();      
   }  
 }  

Board POCO Sample:

 public class Board  
 {  
   [Key]  
   public int BoardId { get; set; }  
   [Required, MaxLength(128)]  
   public string Title { get; set; }  
   public virtual ICollection<Bookmark> Bookmarks { get; set; }  
   public Board()  
   {  
     Bookmarks = new HashSet<Bookmark>();  
   }  
 }  

Tag POCO Sample:

 public class Tag  
 {  
   [Key]  
   public int TagId { get; set; }  
   [Required, MaxLength(64)]  
   public string Title { get; set; }  
   public virtual ICollection<Bookmark> Bookmarks { get; set; }  
   public Tag()  
   {  
     Bookmarks = new HashSet<Bookmark>();  
   }  
 }  

}

Note there are certain fields above which are Required; this allows for validation via attribute decoration. If you require a different primary key field name you can decorate your primary key with the [Key] attribute. You have the option to have a custom name or use the default convention which is done by specifying Id as the primary key.

Create a derived type BookyDbContext 

Creating a derived type BookyDbContext is as simple as inheriting from DbContext, creating a constructor that specifies a connection string ("Sql_CE" in our case) passing this parameter to the base class. Next the requirement is for database table names to not be pluralized and when the model changes I want to Drop and the Create Database. There are model builder configurations being added that will be touched upon later. 

BookyDbContext Code Sample:

public class BookyDbContext : DbContext 
{
    public BookyDbContext()
    : base(nameOrConnectionString: "Sql_CE") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            // Use singular table names
       modelBuilder.Conventions.Remove();
       Database.SetInitializer(new DropCreateDatabaseIfModelChanges());

       modelBuilder.Configurations.Add(new BookmarkConfiguration());
       modelBuilder.Configurations.Add(new TagConfiguration());
    }

    public DbSet Bookmarks { get; set; }

    public DbSet Users { get; set; }

    public DbSet Tags { get; set; }

    public DbSet Boards { get; set; }
}

You need a DbSet Property for each model class.

Using EntityTypeConfiguration to Create Model Relationships 


class BookmarkConfiguration : EntityTypeConfiguration
{
    internal BookmarkConfiguration()
    {
        this.HasMany(b => b.Tags)
            .WithMany(t => t.Bookmarks)
            .Map(mc =>
            {
                mc.MapLeftKey("BookmarkId");
                mc.MapRightKey("TagId");
                mc.ToTable("BookmarkTag");
            });

        this.HasOptional(bd => bd.Board)
            .WithMany(b => b.Bookmarks)
            .Map(x => x.MapKey("BoardId"));
    }

}

internal class TagConfiguration : EntityTypeConfiguration
{
    internal TagConfiguration()
    {
        this.HasMany(t => t.Bookmarks).WithMany(b => b.Tags).Map(
            mc =>
                {
                    mc.MapLeftKey("TagId");
                    mc.MapRightKey("BookmarkId");
                    mc.ToTable("BookmarkTag");
                });
    }
}

Assure you have these classes configured in BookyDbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Use singular table names
    modelBuilder.Conventions.Remove();
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges());

    modelBuilder.Configurations.Add(new BookmarkConfiguration());
    modelBuilder.Configurations.Add(new TagConfiguration());

}

Sample Code to Add/Update/Delete/Read data


public Bookmark GetById(int id)
{
    using (var context = new BookyDbContext())
    {
        var bookmark = context.Bookmarks.FirstOrDefault(o => o.BookmarkId == id);
        return bookmark;
    }
}

public IEnumerable GetAll(int userId)
{
    using (var context = new BookyDbContext())
    {
        return context.Bookmarks.Where(o => o.UserId == userId).ToList();
    }
}

public List GetPagedEntity(int skip, int take, int userId)
{
    using (var context = new BookyDbContext())
    {
        return context.Bookmarks.Where(o => o.UserId == userId).OrderBy(o => o.Title).Skip(skip).Take(take).ToList();
    }
}

public Bookmark GetBookmarkByUri(string Uri)
{
    using (var context = new BookyDbContext())
    {
        var bookmark = context.Bookmarks.FirstOrDefault(o => o.Url == Uri);

        return bookmark;
    }
}

public Bookmark Delete(int id, int userId)
{
    //var bookmark = GetById(id, userId);

    using (var context = new BookyDbContext())
    {
        var bookmark = context.Bookmarks.FirstOrDefault(o => o.BookmarkId == id);
               
            context.Bookmarks.Remove(bookmark);
            context.SaveChanges();  
         
        return bookmark;
    }
}

public Bookmark Add(Bookmark item, int userId)
{
    using (var context = new BookyDbContext())
    {
        Tag tag = SaveDefaultTagIfNotExists(context);
        item.DtCreated = DateTime.Now;
        item.UserId = userId;
        item.Tags.Add(tag);
        context.Bookmarks.Add(item);
        context.SaveChanges();

        Board board = this.SaveDefaultBoardIfNotExists(context, item);
    }

    return item;
}

private Tag SaveDefaultTagIfNotExists(BookyDbContext context)
{
    //Check if the tag exists first, if not then add the tag
    var existTag = context.Tags.FirstOrDefault(o => o.Title == "General");

    if (existTag != null)
    {
        return existTag;
    }
    else
    {
        var tag = new Tag();
        tag.Title = "General";
        context.Tags.Add(tag);
        context.SaveChanges();
        return tag;
    }
}

private Board SaveDefaultBoardIfNotExists(BookyDbContext context, Bookmark bookmark)
{
    //Check if the tag exists first, if not then add the tag
    var existBoard = context.Boards.FirstOrDefault(o => o.Title == "General");

    if (existBoard != null)
    {
        existBoard.Bookmarks.Add(bookmark);
        context.SaveChanges();
        return existBoard;
    }
    else
    {
        var board = new Board();
        board.Title = "General";
        board.Bookmarks.Add(bookmark);
        context.Boards.Add(board);
        context.SaveChanges();
        return board;
    }
}

public Bookmark Update(Bookmark item, int userId)
{
    var bookmark = GetById(item.BookmarkId, userId);
    using (var context = new BookyDbContext())
    {
        if (bookmark != null)
        {
            bookmark.Title = item.Title;
            bookmark.Description = item.Description;
            bookmark.Read = item.Read;
            bookmark.Starred = item.Starred;
            bookmark.Url = item.Url;
       
            context.SaveChanges();
        }
    }

    return item;
}


Sunday, August 18, 2013

Building Booky - A look at developing Booky; An online service to manage, share and find your bookmarks.

Booky is an online service that allows you to manage, share and find bookmarks. Development of booky code base has gone through two phases of development. Each phase includes the following architectural layers:

Phase 1 - booky feature development - Prototyping

  • Data Layer (Entity Framework Code First with SqlCE RDBMS for prototyping 
  • Business Layer
  • RESTFul API Layer - MS Web API
  • User Interface Layer (AngularJS)

Phase 2 - Alpha version

  • Azure Table Storage
  • Business Layer
  • RESTFul API Layer - MS Web API
  • User Interface Layer (AngularJS)

The alpha version of booky is using Azure Table Storage for the backend. To speed development, a backend implementation was done in Entity Framework Code First with SqlCE RDBMS. This was done so that I could focus on a primary problem domain: booky feature development. The secondary problem domain was development of the User Interface layer with AngularJS.


In a three part blog series I discover and outline some of the aspects that went into developing booky and some of the aspects I learned while developing Booky:

Monday, July 29, 2013

Abstract Classes vs Interfaces

In this post I will review when Abstract Classes can be used over Interfaces and vice versa. To begin I start with a definition for Abstract Class and Interface. Then I outline the features and then finish out this post with the pressing question: When should Abstract Classes (or vice versa) be used over Interfaces? In a later post I will provide an example of Interfaces used in Booky.

Before we explore Abstract classes and interfaces let’s define them using Microsoft’s MSDN definitions:

Abstract Classes 

They are classes that cannot be instantiated, and are frequently either partially implemented, or not at all implemented. See http://msdn.microsoft.com/en-us/library/k535acbf(v=VS.71).aspx

An abstract class provides a common definition of a base class that multiple derived classes can share.

Interfaces

An interface defines a contract. A class or struct that implements an interface must adhere to its contract. See http://msdn.microsoft.com/en-us/library/87d83y5b(v=vs.71).aspx An interface contains definitions for a group of related functionalities that a class or a struct can implement.

Let’s explore the features of Abstract Classes and Interfaces before we determine the best or optimal time to use one over the other.

Interface Features
  • Members are automatically public
  • May contain properties, methods, events and indexers.
  • An interface can inherit from one or more base interfaces
  • Interfaces can be implemented by classes and structs.
Abstract Class Features
  • Abstract class cannot be instantiated.
  • Members have access modifiers (i.e. public, private)
  • May contain fields, properties, constructors, destructors, methods, events and indexers.
  • It is not possible to modify an abstract class with the sealed modifier, which means that the class cannot be inherited.
  • A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.
When should Abstract Classes (or vice versa) be used over Interfaces? 

A comparison between the two (fix with full name)

Comparison


Abstract ClassesInterfaces
- They may contain implementation code- They not contain implementation code
- They may only inherit from a single base class - They may implement any number of interfaces 

Use Abstract Classes when you have common shared implementation code. For example if your component requirement has shared functionality among objects then abstract classes may be a candidate for consideration when designing the system. 

Use Interfaces when the functionality you are creating will be used across a wide range of objects. When create small pieces of functionality then interfaces are a good choice.



Saturday, June 29, 2013

Voltage, Current, Resistance & Ohm's Law

The three basic principles of this entry can be explained using electrons, or more specifically, the charge they create:
  • Voltage is the difference in charge between two points.
  • Current is the rate at which charge is flowing.
  • Resistance is a material’s tendency to resist the flow of charge (current).
Voltage

Voltage is a specific measure of potential energy that is always relative between two points. The different in charge between two points is called Voltage. 
The unit “volt” is named after the Italian physicist Alessandro Volta who invented what is considered the first chemical battery. Voltage is represented in equations and schematics by the letter “V”.


Current

Current is the flow of electrons/charged particles

Resistance

Resistance is how difficult it is for the charges to flow through an electrical component or from one point to another in an electrical circuit. The SI unit of electrical resistance is the ohm (Ω). Resistance was discovered by Georg Simon Ohm, who was born in Bavaria in 1787 and worked in obscurity for much of his life, studying the nature of electricity using metal wire that he had to make for himself (you couldn’t truck on down to Home Depot for a spool of hookup wire back in the early 1800s). Despite his limited resources and inadequate mathematical abilities, Ohm was able to demonstrate in 1827 that the electrical resistance of a conductor such as copper varied in inverse proportion with its area of cross-section, and the current flowing through it is proportional to the voltage applied to it, as long as temperature is held constant.

Ohm's Law

Combining the elements of voltage, current, and resistance, Ohm developed the formula:

V = I x R
  • V = Voltage in volts
  • I = Current in amps
  • R = Resistance in ohms
Related links:
  1. Reference
  2. Reference
  3. Reference
  4. Reference