다음을 통해 공유


Async Asp.Net MVC Solution Architecture with Repository Pattern by Unity via Service Layer

Introduction

Asp.Net MVC Solution Architecture project presents a flexible layered architecture is inspired from some of the best solutions structure's available incorporating the best practices like Async Repository Pattern, Dependency Injection in ASP.NET MVC using Unity IoC Container, Entity Framework, POCO classes and Application Service layer for BAL.

It re-uses the Entity models in various layers. At the same time other View Models for UI and Business Models can be introduced as when required for complex operations.

Background

ASP.Net comes up with the default solution template with separation of concerns. But at times when we prepare solution architecture we need to have the flexibility built in the DAL, BAL and Presentation layers to take care of dynamic scenarios. What if apart from the ASP.Net MVC one also needs a Web API. What if the Entity Framework needs to be replaced with other object-relational mapper. How easy it would be to modify one layer without touching other layers?

Using the code

First the database was created as database first approach was used. The detail code can be found and further contribution can be made in GitHub

The demo uses a simple table created in SQL Server Express:

StarDesc Table in Database

CREATE TABLE [dbo].[StarDesc] (

 [StarName]            NVARCHAR (150) NULL,

 [StarSize]            NVARCHAR (50)  NULL,

 [StarDistanceFromSun] NVARCHAR (50)  NULL,

 [StarGalaxyName]      NVARCHAR (50)  NULL,

 [StarBrightness]      NVARCHAR (50)  NULL,

 [SpectralType]        NVARCHAR (50)  NULL,

 [Id]                  INT            IDENTITY (1, 1) NOT NULL,

 CONSTRAINT [PK_StarDesc] PRIMARY KEY CLUSTERED ([Id] ASC)

 );

SET IDENTITY_INSERT [dbo].[StarDesc] ON
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'10 Lacertae', N'8.27', N'2300', N'Lacerta OB1', N'-4.40', N'O9V', 1)
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'Rigel', N'79', N'863', N'Orion', N'-7.84', N'B8Ia', 2)
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'Sirius ', N'1.71', N'8.6', N'Canis Major', N'1.42', N'A1V', 3)
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'Canopus', N'71', N'320', N'Carina', N'-5.71', N'A9II', 4)
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'Sun', N'1', N'0', N'Milky Way', N'4.83', N'G2V', 5)
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'Arcturus', N'25.4', N'36.66', N'Bootes', N'-0.32', N'K0III', 6)
INSERT INTO [dbo].[StarDesc] ([StarName], [StarSize], [StarDistanceFromSun], [StarGalaxyName], [StarBrightness], [SpectralType], [Id]) VALUES (N'Betelgeuse', N'1180', N'642.5', N'Orion', N'-5.85', N'M1Ia', 7)
SET IDENTITY_INSERT [dbo].[StarDesc] OFF

The entire Solution structure is shown in the snapshots below

Infrastructure

Domain

Presentation

Using the 'Entity Framework Power Tools Beta 4 (Visual Studios Extension)' we auto-generate the entity classes, mapper classes and the database context class, namely 'StarDesc.cs', 'StarDescMap.cs' and 'StarSystemContext.cs'.

StarDesc.cs

namespace CG.StarSystem.Data.Models
{
    public partial class StarDesc
    {
        public int Id { get; set; }
        public string StarName { get; set; }
        public string StarSize { get; set; }
        public string StarDistanceFromSun { get; set; }
        public string StarGalaxyName { get; set; }
        public string StarBrightness { get; set; }
        public string SpectralType { get; set; }
    }
}

StarDescMap.cs

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;

namespace CG.StarSystem.Data.Models.Mapping
{
    public class StarDescMap : EntityTypeConfiguration<StarDesc>
    {
        public StarDescMap()
        {
            // Primary Key
            this.HasKey(t => t.Id);

            // Properties
            this.Property(t => t.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            this.Property(t => t.StarName)
                .HasMaxLength(150);

            this.Property(t => t.StarSize)
                .HasMaxLength(50);

            this.Property(t => t.StarDistanceFromSun)
                .HasMaxLength(50);

            this.Property(t => t.StarGalaxyName)
                .HasMaxLength(50);

            this.Property(t => t.StarBrightness)
                .HasMaxLength(50);

            this.Property(t => t.SpectralType)
                .HasMaxLength(50);

            // Table & Column Mappings
            this.ToTable("StarDesc");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.StarName).HasColumnName("StarName");
            this.Property(t => t.StarSize).HasColumnName("StarSize");
            this.Property(t => t.StarDistanceFromSun).HasColumnName("StarDistanceFromSun");
            this.Property(t => t.StarGalaxyName).HasColumnName("StarGalaxyName");
            this.Property(t => t.StarBrightness).HasColumnName("StarBrightness");
            this.Property(t => t.SpectralType).HasColumnName("SpectralType");
        }
    }
}

StarSystemContext.cs

using System.Data.Entity;
using CG.StarSystem.Data.Models.Mapping;

namespace CG.StarSystem.Data.Models
{
    public partial class StarSystemContext : DbContext
    {
        static StarSystemContext()
        {
            Database.SetInitializer<StarSystemContext>(null);
        }

        public StarSystemContext()
            : base("Name=StarSystemContext")
        {
            // the terrible hack
            var ensureDLLIsCopied =
                    System.Data.Entity.SqlServer.SqlProviderServices.Instance;
        }

        public DbSet<SpectralClassesSubType> SpectralClassesSubTypes { get; set; }
        public DbSet<StarDesc> StarDescs { get; set; }
        public DbSet<StarTypeByLuminosityClass> StarTypeByLuminosityClasses { get; set; }
        public DbSet<StarTypeBySpectralClass> StarTypeBySpectralClasses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new SpectralClassesSubTypeMap());
            modelBuilder.Configurations.Add(new StarDescMap());
            modelBuilder.Configurations.Add(new StarTypeByLuminosityClassMap());
            modelBuilder.Configurations.Add(new StarTypeBySpectralClassMap());
        }
    }
}

IStarDescRepository.cs

using CG.StarSystem.Data.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace CG.StarSystem.Repository.StarDescs
{
    
    public interface IStarDescRepository: IDisposable
    {
        Task<List<StarDesc>> GetStarDescsAsync();
        Task<StarDesc> GetStarDescByIdAsync(int? id);
        Task CreateStarAsync(StarDesc stardesc);
        Task DeleteStarAsync(int? id);
        Task EditStarDescAsync(StarDesc stardesc);
    }
}

StarDescRepository.cs

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using CG.StarSystem.Data.Models;
using System.Data.Entity;

namespace CG.StarSystem.Repository.StarDescs
{
    public class StarDescRepository : IStarDescRepository, IDisposable
    {

        private StarSystemContext _context;

        /// <summary>
        ///     Create a new instance of <see cref="StarDescRepository" />.
        /// </summary>
        /// <param name="transaction">Active transaction</param>
        /// <exception cref="ArgumentNullException">transaction</exception>
        public StarDescRepository()
        {
            _context = new StarSystemContext();

        }

        
        public async Task<List<StarDesc>> GetStarDescsAsync()
        {
            return await _context.StarDescs.ToListAsync();
        }

        public async Task<StarDesc> GetStarDescByIdAsync(int? id)
        {
            return await _context.StarDescs.FindAsync(id);
        }

        public  async Task CreateStarAsync(StarDesc stardesc)
        {
             _context.StarDescs.Add(stardesc);
            await _context.SaveChangesAsync(); 
        }

        public async Task EditStarDescAsync(StarDesc stardesc)
        {
            _context.Entry(stardesc).State = EntityState.Modified;
            await _context.SaveChangesAsync();
        }

        public async Task DeleteStarAsync(int? id)
        {
            StarDesc stardesc = await _context.StarDescs.FindAsync(id);
            _context.StarDescs.Remove(stardesc);
            await _context.SaveChangesAsync();
        }
           
        
       

        #region IDisposable Support
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    
                    _context.Dispose();
                }

                disposedValue = true;
            }
        }

        // This code added to correctly implement the disposable pattern.
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }


        #endregion
    }
}

IStarDescService.cs

using CG.StarSystem.Data.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace CG.StarSystem.ApplicationServices
{
    public interface IStarDescService : IDisposable
    {
        Task<List<StarDesc>> GetAllStarsAsync();
        Task<StarDesc> GetStarDescriptionByIdAsync(int? id);
        Task AddStarAsync(StarDesc stardesc);
        Task DeleteStarAsync(int? id);
        Task EditStarDescAsync(StarDesc stardesc);

    }
}

StarDescService.cs

using CG.StarSystem.Data.Models;
using CG.StarSystem.Repository.StarDescs;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace CG.StarSystem.ApplicationServices
{
    public class StarDescService : IStarDescService, IDisposable
    {
        private readonly IStarDescRepository _StarDescRepository;

        //public StarDescService(IStarDescRepository IStarDescRepository) {
        //    _IStarDescRepository = IStarDescRepository;
        //}
        public StarDescService()
        {
            _StarDescRepository =  new StarDescRepository();
           
        }

        public async Task<List<StarDesc>> GetAllStarsAsync()
        {

            return await _StarDescRepository.GetStarDescsAsync();
        }

        public async Task<StarDesc> GetStarDescriptionByIdAsync(int? id)
        {
           
            return await _StarDescRepository.GetStarDescByIdAsync(id);
        }

        public async Task AddStarAsync(StarDesc stardesc)
        {

            await _StarDescRepository.CreateStarAsync(stardesc);
        }

        public async Task DeleteStarAsync(int? id)
        {

            await _StarDescRepository.DeleteStarAsync(id);
        }

        public async Task EditStarDescAsync(StarDesc stardesc)
        {

             await _StarDescRepository.EditStarDescAsync(stardesc);
        }

       


        #region IDisposable Support
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    _StarDescRepository.Dispose();
                }

                disposedValue = true;
            }
        }

        // This code added to correctly implement the disposable pattern.
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion


    }
}

StarDescController.cs

using System.Collections.Generic;
using System.Web.Mvc;
using CG.StarSystem.ApplicationServices;
using CG.StarSystem.Data.Models;
using System.Threading.Tasks;
using System.Net;

namespace CG.StarSystem.Web.Controllers
{
    public class StarDescController : Controller
    {
        private readonly IStarDescService _service;
        public StarDescController(IStarDescService service) {
            _service = service;
        }

        // GET: StarDesc
        public async Task<ActionResult> Index()
        {
            IList<StarDesc> stars = await _service.GetAllStarsAsync();
            
            return View(stars);
        }
        public async Task<ActionResult> Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            StarDesc star = await _service.GetStarDescriptionByIdAsync(id);
            if (star == null)
            {
                return HttpNotFound();
            }
            return View(star);
        }

        // GET: Notes/Create
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create([Bind(Include = "StarName,StarSize,StarDistanceFromSun,StarGalaxyName,StarBrightness,SpectralType")] StarDesc stardesc)
        {
            if (ModelState.IsValid)
            {
               
                await _service.AddStarAsync(stardesc);
                
                return RedirectToAction("Index");
            }

            return View(stardesc);
        }
        // GET: Notes/Edit/5
        public async Task<ActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            StarDesc stardesc = await _service.GetStarDescriptionByIdAsync(id);
            if (stardesc == null)
            {
                return HttpNotFound();
            }
            return View(stardesc);
        }


        // POST: Notes/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit([Bind(Include = "Id,StarName,StarSize,StarDistanceFromSun,StarGalaxyName,StarBrightness,SpectralType")] StarDesc stardesc)
        {
            if (ModelState.IsValid)
            {
                await _service.EditStarDescAsync(stardesc);
                
                return RedirectToAction("Index");
            }
            return View(stardesc);
        }

        // GET: Notes/Delete/5
        public async Task<ActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            StarDesc stardesc = await _service.GetStarDescriptionByIdAsync(id);
            if (stardesc == null)
            {
                return HttpNotFound();
            }
            return View(stardesc);
        }

        // POST: Notes/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> DeleteConfirmed(int id)
        {
            await _service.DeleteStarAsync(id);
           
           
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _service.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

_Layout.cshtml

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
        @RenderBody()
    </div>
</body>
</html>

Index.cshtml

@using CG.StarSystem.Data.Models;
@model IEnumerable<StarDesc>
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@{ 
    ViewBag.Title = "Star System";
        }
<h2>Star List</h2>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table border="1">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Id)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.StarName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.StarSize)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.StarDistanceFromSun)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.StarGalaxyName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.StarBrightness)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.SpectralType)
        </th>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.StarName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.StarSize)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.StarDistanceFromSun)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.StarGalaxyName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.StarBrightness)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.SpectralType)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>


    }
</table>

Details.cshtml

@using CG.StarSystem.Data.Models;
@model StarDesc

@{
    ViewBag.Title = "Details";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

    </style>
<h2>Details</h2>

<div>
    <h4>Star Description</h4>
    <hr />
    <dl class="dl-horizontal" border="1">
        <dt>
            @Html.DisplayNameFor(model => model.StarName)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.StarName)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.StarSize)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.StarSize)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.StarDistanceFromSun)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.StarDistanceFromSun)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.StarGalaxyName)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.StarGalaxyName)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.StarBrightness)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.StarBrightness)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.SpectralType)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.SpectralType)
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
    @Html.ActionLink("Back to List", "Index")
</p>

Create.cshtml, Delete.cshtml & Edit.cshtml were generated by scaffolding the views from controller action methods.

The configuration files codes of various project are given below

In the project CG.StarSystem.Data

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

In the project CG.StarSystem.Repository

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>

In the project CG.StarSystem.Web

Web.config

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301880
  -->
<configuration>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
  </system.web>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <connectionStrings>
    <add name="StarSystemContext" connectionString="Data Source=pgcg\sqlexpress;Initial Catalog=StarSystem;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Finally the Unity Config file in the project CG.StarSystem.Web

UnityConfig.cs

using System;
using Microsoft.Practices.Unity;
//using CG.StarSystem.Repository;
using CG.StarSystem.ApplicationServices;
//using CG.StarSystem.Repository.StarDescs;

namespace CG.StarSystem.Web.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

       
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

     
        public static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterType<IUnityContainer, UnityContainer >(new PerRequestLifetimeManager());
            container.RegisterType<IStarDescService, StarDescService>(new PerRequestLifetimeManager());
            //container.RegisterType<IStarDescRepository, StarDescRepository>(new PerRequestLifetimeManager());
        }
    }
}

Points of Interest

1. Project made in Visual Studios Community Edition 2015.
2. The 'Entity Framework Power Tools Beta 4 Extension's file named 'extension.vsixmanifest' had to be modified. It was used for 'Reverese Engineer Code First' for generating POCO classes.
3. Almost ended up by using 'Grifin DAL Repo Generator' but deleted the codes as it uses ADO.Net transactions and not entity framework.
4. Please check the video in point 2 below if the code looks over whelming. The entire project can be made in less than an hour by using visual studios extensions and tools. Also community edition has 'Resharper' in built.

Bibliography

1. https://stackoverflow.com/questions/37724049/using-repository-patern-when-using-async-await-methods-asp-net-mvc5-ef
2. URF (Unit of Work & Repository Framework) in ASP.NET MVC 5 with Entity Framework 6 & Unity 3 - v2
https://www.youtube.com/watch?v=QwwfTWMrM9k
3. http://www.itworld.com/article/2700950/development/a-generic-repository-for--net-entity-framework-6-with-async-operations.html
4. http://www.dotnetcurry.com/ShowArticle.aspx?ID=617
5. https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application
6. http://thedatafarm.com/data-access/installing-ef-power-tools-into-vs2015/
7. http://hannesdorfmann.com/android/evolution-of-the-repository-pattern

History

1. Made the method asynchronous across the layers like View, Controller, Services and Repository

2. Initially had the repository class creation from the UnityConfig.cs, which was changed. Now the Repository class instances are created from the Service layer so that there would be no dependency of repository later with the Presentation Layer.

3. Had to add the lines below in StarSystemContext.cs

// the terrible hack
            var ensureDLLIsCopied =
                    System.Data.Entity.SqlServer.SqlProviderServices.Instance;