pr0g33k

 collapse all
  1. Next Steps: Adding a Service Layer and Validation

    I've been using the Repository and UnitOfWork I created in my previous post in all of my projects with quite a lot of success. One of the things I noticed, though, is that there were occasions when I repeated the same LINQ query in several controller methods with the same business logic applied to the data. I also had cases where there was validation logic in my controllers that needed to be shared. That's no bueno. I set out to centralize that code but quickly realized that a lot more work was needed.

    I won't go through all of the project setup - you can see that in my previous post - but I will point out some changes I made in my updated code. I mentioned last time that it would be best to separate the ORM-specific repository and unit of work implementations into their own assembly so I did that in my updated Recreation project (see Core.EntityFramework). I also updated Entity Framework to version 6 and added asynchronous methods to the Repository and UnitOfWork interfaces and implementations.

    One of the cases where I noticed I was repeating the same query against the data across multiple controller methods was when I added the same dropdown list to several views. An example of this might be a view to create a Reservation and another view to edit a Reservation. Both controller methods might create SelectLists for facilities and guests and pass them to the view using the ViewBag. There would also likely be two methods for Edit and two for Create where these services would be used - one for the initial loading of the view and another for the HttpPost. The queries for facilities and guests would be the same in all of the controller methods so it makes sense to centralize that code somewhere. When I searched online for a pattern that fit this use case, the Service Layer pattern seemed to be the most appropriate:

    A Service Layer defines an application's boundary and its set of available operations from the perspective of interfacing client layers. It encapsulates the application's business logic, controlling transactions and coordinating responses in the implementation of its operations.

    The Service Layer classes for the Guest and Facility domain models look like this:

    namespace Recreation.Data.Services
    {
        public interface IFacilityService : IDisposable
        {
            Dictionary<Int32, String> GetSelections();
        }
    
        public class FacilityService : IFacilityService
        {
            private readonly IRepository<Facility> _FacilityRepository;
    
            public FacilityService(IRepository<Facility> facilityRepository)
            {
                _FacilityRepository = facilityRepository;
            }
    
            public Dictionary<Int32, String> GetSelections()
            {
                return (from q in _FacilityRepository.GetQueryable()
                        select new { q.Id, q.Name }).OrderBy(o => o.Name).ToDictionary(d => d.Id, d => d.Name);
            }
    
            public void Dispose()
            {
                if (_FacilityRepository != null)
                    _FacilityRepository.Dispose();
            }
        }
    }
    namespace Recreation.Data.Services
    {
        public interface IGuestService : IDisposable
        {
            Dictionary<Int32, String> GetSelections();
        }
    
        public class GuestService : IGuestService
        {
            private readonly IRepository<Guest> _GuestRepository;
    
            public GuestService(IRepository<Guest> facilityRepository)
            {
                _GuestRepository = facilityRepository;
            }
    
            public Dictionary<Int32, String> GetSelections()
            {
                return (from q in _GuestRepository.GetQueryable()
                        select new { q.Id, q.FirstName, q.LastName }).OrderBy(o => o.LastName).ToDictionary(d => d.Id, d => String.Format("{0}, {1}", d.LastName, d.FirstName));
            }
    
            public void Dispose()
            {
                if (_GuestRepository != null)
                    _GuestRepository.Dispose();
            }
        }
    }

    You will then need to register these services with Unity so that you can inject them into the controller:

    namespace Recreation.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;
            });
    
            /// <summary>
            /// Gets the configured Unity container.
            /// </summary>
            public static IUnityContainer GetConfiguredContainer()
            {
                return container.Value;
            }
    
            #endregion
    
            /// <summary>Registers the type mappings with the Unity container.</summary>
            /// <param name="container">The unity container to configure.</param>
            /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
            /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
            public static void RegisterTypes(IUnityContainer container)
            {
                // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
                // container.LoadConfiguration();
                // TODO: Register your types here
    
                //Data Access
                container.RegisterType<IObjectContextAdapter, RecreationContext>(new PerRequestLifetimeManager());
                container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
                container.RegisterType<IUnitOfWork, UnitOfWork>();
    
                //Services
                container.RegisterType<IFacilityService, FacilityService>();
                container.RegisterType<IGuestService, GuestService>();
            }
        }
    }

    The ReservationController would then consume those services like this (I only included the Edit methods):

    namespace Recreation.Web.Controllers
    {
        public class ReservationController : Controller
        {
            private readonly IRepository<Reservation> _ReservationRepository;
            private readonly IFacilityService _FacilityService;
            private readonly IGuestService _GuestService;
            private readonly IUnitOfWork _UnitOfWork;
    
            public ReservationController(IRepository<Reservation> reservationRepository, IFacilityService facilityService, IGuestService guestService, IUnitOfWork unitOfWork)
            {
                _ReservationRepository = reservationRepository;
                _FacilityService = facilityService;
                _GuestService = guestService;
                _UnitOfWork = unitOfWork;
            }
    
            public ActionResult Index()
            {
                return View(_ReservationRepository.GetAll());
            }
    
            public ActionResult Edit(Int32 id = 0)
            {
                var reservation = _ReservationRepository.SingleOrDefault(r => r.Id == id);
    
                if (reservation == null)
                    return HttpNotFound();
    
                ViewBag.FacilityId = new SelectList(_FacilityService.GetSelections(), "Key", "Value", reservation.FacilityId);
                ViewBag.GuestId = new SelectList(_GuestService.GetSelections(), "Key", "Value", reservation.GuestId);
                
                return View(reservation);
            }
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Edit(Reservation reservation)
            {
                _ReservationRepository.Attach(reservation, EntityStatus.Modified);
    
                if (ModelState.IsValid)
                {
                    try
                    {
                        _UnitOfWork.SaveChanges();
                    }
                    catch (ConcurrencyException)
                    {
                        ModelState.AddModelError(String.Empty, "The record you attempted to edit was modified by another user after you got the original value. Your edit operation was canceled. If you still want to edit this record, save it again.");
                    }
                    catch (Exception)
                    {
                        ModelState.AddModelError(String.Empty, "Unable to save changes. Please try again.");
                    }
                }
    
                ViewBag.FacilityId = new SelectList(_FacilityService.GetSelections(), "Key", "Value", reservation.FacilityId);
                ViewBag.GuestId = new SelectList(_GuestService.GetSelections(), "Key", "Value", reservation.GuestId);
    
                return View(reservation);
            }
    
            protected override void Dispose(Boolean disposing)
            {
                if (disposing)
                {
                    _ReservationRepository.Dispose();
                    _FacilityService.Dispose();
                    _GuestService.Dispose();
                    _UnitOfWork.Dispose();
                }
    
                base.Dispose(disposing);
            }
        }
    }

    When the controller is created, Unity instantiates the Repository<Reservation> object specified in the controller's constructor. When it sees the Service Layer references, it instantiates the Repository<> objects in their respective constructors before instantiating the Service Layer objects.

    The Edit.cshtml view looks like this:

    @model Recreation.Data.Models.Reservation
    @{
        ViewBag.Title = "Edit Reservation";
    }
    <p>@Html.ActionLink("View Reservations", "Index")</p>
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>@ViewBag.Title</legend>
            @Html.HiddenFor(m => m.Id)
            @Html.HiddenFor(m => m.ConcurrencyToken)
            <ol>
                <li>
                    @Html.LabelFor(m => m.FacilityId)
                    @Html.DropDownList("FacilityId", "Select a Facility")
                    @Html.ValidationMessageFor(m => m.FacilityId)
                </li>
                <li>
                    @Html.LabelFor(m => m.GuestId)
                    @Html.DropDownList("GuestId", "Select a Guest")
                    @Html.ValidationMessageFor(m => m.GuestId)
                </li>
                <li>
                    @Html.LabelFor(m => m.StartDateTime)
                    @Html.TextBoxFor(m => m.StartDateTime)
                    @Html.ValidationMessageFor(m => m.StartDateTime)
                </li>
                <li>
                    @Html.LabelFor(m => m.EndDateTime)
                    @Html.TextBoxFor(m => m.EndDateTime)
                    @Html.ValidationMessageFor(m => m.EndDateTime)
                </li>
            </ol>
            <input type="submit" value="Submit" />
        </fieldset>
    }

    Validation

    Where to place validation logic - especially logic that isn't easily covered by MVC's HTML helper methods - is something that I've struggled with when it comes to MVC. Once I started down the path of creating a Service Layer, though, this became somewhat easier. I found this article on asp.net that explains placing validation logic in a Service Layer:

    So, application flow control logic belongs in a controller and data access logic belongs in a repository. In that case, where do you put your validation logic? One option is to place your validation logic in a service layer. A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer. The service layer contains business logic. In particular, it contains validation logic.

    Stephen Walther's approach is a good one but it didn't quite smell right to me - particularly with my Service Layer approach and my usage of the Inversion of Control (IoC) pattern using Unity. That led me to this question on Stack Overflow. The accepted answer by "Steven" was exactly what I needed. After some scrubbing and polishing, I ended up with what I think is an excellent way to do model and data validation in the Service Layer with MVC. I won't bore you with the details because "Steven" does a pretty good job of explaining everything.

    The ReservationValidator looks like this:

    namespace Recreation.Data.Validation
    {
        public class ReservationValidator : Validator<Reservation>
        {
            protected override IEnumerable<ValidationResult> Validate(Reservation entity)
            {
                if (entity.FacilityId <= 0)
                    yield return new ValidationResult("FacilityId", "You must select a Facility");
    
                if (entity.GuestId <= 0)
                    yield return new ValidationResult("GuestId", "You must select a Guest");
    
                if (entity.EndDateTime < entity.StartDateTime)
                    yield return new ValidationResult("EndDateTime", "The End Date/Time must be greater than the Start Date/Time");
    
                if ((entity.EndDateTime - entity.StartDateTime).TotalHours < 1)
                    yield return new ValidationResult("EndDateTime", "The End Date/Time must be at least one hour greater than the Start Date/Time");
            }
        }
    }

    And the ReservationService looks like this:

    namespace Recreation.Data.Services
    {
        public interface IReservationService : IDisposable
        {
            IEnumerable<Reservation> GetAll();
            Reservation GetById(Int32 id);
            void Update(Reservation reservation);
        }
    
        public class ReservationService : IReservationService
        {
            private readonly IRepository<Reservation> _ReservationRepository;
            private readonly IUnitOfWork _UnitOfWork;
            private readonly IValidationProvider _ValidationProvider;
    
            public ReservationService(IRepository<Reservation> reservationRepository, IUnitOfWork unitOfWork, IValidationProvider validationProvider)
            {
                _ReservationRepository = reservationRepository;
                _UnitOfWork = unitOfWork;
                _ValidationProvider = validationProvider;
            }
    
            public IEnumerable<Reservation> GetAll()
            {
                return _ReservationRepository.GetAll();
            }
    
            public Reservation GetById(Int32 id)
            {
                return _ReservationRepository.SingleOrDefault(r => r.Id == id);
            }
    
            public void Update(Reservation reservation)
            {
                _ValidationProvider.Validate(reservation);
                _ReservationRepository.Attach(reservation, EntityStatus.Modified);
                _UnitOfWork.SaveChanges();
            }
    
            public void Dispose()
            {
                if (_ReservationRepository != null)
                    _ReservationRepository.Dispose();
    
                if (_UnitOfWork != null)
                    _UnitOfWork.Dispose();
            }
        }
    }

    Registering the validators with Unity is pretty slick. The UnityConfig code now looks like this:

    namespace Recreation.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;
            });
    
            /// <summary>
            /// Gets the configured Unity container.
            /// </summary>
            public static IUnityContainer GetConfiguredContainer()
            {
                return container.Value;
            }
    
            #endregion
    
            /// <summary>Registers the type mappings with the Unity container.</summary>
            /// <param name="container">The unity container to configure.</param>
            /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
            /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
            public static void RegisterTypes(IUnityContainer container)
            {
                // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
                // container.LoadConfiguration();
                // TODO: Register your types here
    
                //Data Access
                container.RegisterType<IObjectContextAdapter, RecreationContext>(new PerRequestLifetimeManager());
                container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
                container.RegisterType<IUnitOfWork, UnitOfWork>();
    
                //Services
                container.RegisterType<IFacilityService, FacilityService>();
                container.RegisterType<IGuestService, GuestService>();
                container.RegisterType<IReservationService, ReservationService>();
    
                //Validators
                container.RegisterInstance(typeof(IValidationProvider), new ValidationProvider(type => (IValidator)container.Resolve(typeof(Validator<>).MakeGenericType(type))));
                container.RegisterType(typeof(Validator<>), typeof(NullValidator<>));
                container.RegisterType<Validator<Reservation>, ReservationValidator>();
            }
        }
    }

    Using Func<Type, IValidator> as a Factory Pattern to instantiate the appropriate Validator based on the calling type is truly inspired. Kudos to "Steven" for coming up with that one!

    The ReservationController can now be updated to look like this:

    namespace Recreation.Web.Controllers
    {
        public class ReservationController : Controller
        {
            private readonly IReservationService _ReservationService;
            private readonly IFacilityService _FacilityService;
            private readonly IGuestService _GuestService;
    
            public ReservationController(IReservationService reservationService, IFacilityService facilityService, IGuestService guestService)
            {
                _ReservationService = reservationService;
                _FacilityService = facilityService;
                _GuestService = guestService;
            }
    
            public ActionResult Index()
            {
                return View(_ReservationService.GetAll());
            }
    
            public ActionResult Edit(Int32 id = 0)
            {
                var reservation = _ReservationService.GetById(id);
    
                if (reservation == null)
                    return HttpNotFound();
    
                ViewBag.FacilityId = new SelectList(_FacilityService.GetSelections(), "Key", "Value", reservation.FacilityId);
                ViewBag.GuestId = new SelectList(_GuestService.GetSelections(), "Key", "Value", reservation.GuestId);
    
                return View(reservation);
            }
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Edit(Reservation reservation)
            {
                try
                {
                    _ReservationService.Update(reservation);
                }
                catch (ValidationException vex)
                {
                    ModelState.AddErrors(vex);
                }
                catch (ConcurrencyException)
                {
                    ModelState.AddModelError(String.Empty, "The record you attempted to edit was modified by another user after you got the original value. Your edit operation was canceled. If you still want to edit this record, save it again.");
                }
                catch (Exception)
                {
                    ModelState.AddModelError(String.Empty, "Unable to save changes. Please try again.");
                }
    
                ViewBag.FacilityId = new SelectList(_FacilityService.GetSelections(), "Key", "Value", reservation.FacilityId);
                ViewBag.GuestId = new SelectList(_GuestService.GetSelections(), "Key", "Value", reservation.GuestId);
    
                return View(reservation);
            }
    
            protected override void Dispose(Boolean disposing)
            {
                if (disposing)
                {
                    _ReservationService.Dispose();
                    _FacilityService.Dispose();
                    _GuestService.Dispose();
                }
    
                base.Dispose(disposing);
            }
        }
    }

    These changes make the controller much more streamlined. I hope you can get some good use out of this. I've been using combinations of the Repository, UnitOfWork, and Service Layer patterns for the past several months and my projects have resulted in easier-to-read code and better maintainability. You can grab the code for the new Recreation project here.

  2. Getting Started: MVC 4, Entity Framework 5 Code First, and Unity

    After several hours of banging my head against the wall, I finally have a good, working prototype for using Entity Framework 5 Code First in a MVC application with the Unity Inversion of Control (IoC) container for dependency injection. (Say that 3 times fast!) I'm using an IoC container for a couple of reasons. For one, it'll allow me to (somewhat) easily swap out components if I want. For example, if I want to use nHibernate for data access instead of Entity Framework, all I'll need to do is change to what the context, IRepository, and IUnitOfWork interfaces resolve. All of the code I write in the Controllers or elsewhere can stay the same. Another reason I want to use an IoC is because it'll make my components (somewhat) easy to mock (or fake) to supply a way to perform integration tests without having to use the actual services (e.g. I can create an object graph in code and use that in place of making calls to the database). Also, I'll be using the IoC to perform dependency injection (DI) so I'll "inject" my services into the controllers' contructors as well as the contructors of any other objects that depend on my services. This provides an easy way to create services and use them without having to write the code to instantiate them.

    Let's Begin

    First, let's create a MVC Web application. I'm creating a very simple application for an imaginary Parks & Recreation center so I'll call it "Recreation."

    MVC project creation

    For the type of MVC Web application, I'm going to go with the Basic template. I'm also going to create a unit test project but I'll save the unit tests for another post.

    Basic MVC application

    Once the project is created, add a new controller and name it "HomeController."

    Home Controller

    When the HomeController.cs file opens, right-click in the Index() method and select "Add View..."

    Now run the application (F5) to make sure everything compiles and runs.

    Create a Model/Data Access Layer

    Next, we're going to add a separate class library for our entities/models. Add a new project to the solution and name it "Data."

    Data class library

    Once the project is created, add the assembly references for "System.ComponentModel.DataAnnotations." Then use the NuGet Package Manager to add Entity Framework.

    Entity Framework

    Next create folders named "Context" and "Models" and add the following classes:

    Data Project set-up

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace Data.Models
    {
        public class Facility
        {
            [Key]
            public Int32 Id { get; set; }
    
            [StringLength(100)]
            public String Name { get; set; }
            public Int32 SquareFeet { get; set; }
    
            [Timestamp]
            public Byte[] ConcurrencyToken { get; set; }
    
            public virtual ICollection<Reservation> Reservations { get; set; }
        }
    }
        
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace Data.Models
    {
        public class Guest
        {
            [Key]
            public Int32 Id { get; set; }
    
            [StringLength(100)]
            public String FirstName { get; set; }
            [StringLength(100)]
            public String LastName { get; set; }
    
            [Timestamp]
            public Byte[] ConcurrencyToken { get; set; }
    
            public virtual ICollection<Reservation> Reservations { get; set; }
        }
    }
        
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace Data.Models
    {
        public class Reservation
        {
            [Key]
            public Int32 Id { get; set; }
            public DateTime StartDateTime { get; set; }
            public DateTime EndDateTime { get; set; }
    
            [Display(Name = "Facility")]
            public Int32 FacilityId { get; set; }
    
            [Display(Name = "Guest")]
            public Int32 GuestId { get; set; }
    
            [Timestamp]
            public Byte[] ConcurrencyToken { get; set; }
    
            public virtual Facility Facility { get; set; }
            public virtual Guest Guest { get; set; }
        }
    }
        
    using Data.Models;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    
    namespace Data.Context
    {
        public class RecreationContext : DbContext
        {
            public RecreationContext()
                : base("name=DefaultConnection")
            {
            }
    
            public DbSet<Facility> Facilities { get; set; }
            public DbSet<Guest> Guests { get; set; }
            public DbSet<Reservation> Reservations { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
                modelBuilder.Entity<Facility>().Property(p => p.ConcurrencyToken).IsConcurrencyToken();
                modelBuilder.Entity<Guest>().Property(p => p.ConcurrencyToken).IsConcurrencyToken();
                modelBuilder.Entity<Reservation>().Property(p => p.ConcurrencyToken).IsConcurrencyToken();
            }
        }
    }
        

    The "RecreationContext" class is like our gateway to the database. We're first going to use it to create the database. The three DbSet properties establish our tables available through the context. The "OnModelCreating" method allows us to set additional characteristics or properties on the tables as well as do things like change the way columns are named or create specific types of relationships between our tables. Here, we're setting up the "ConcurrencyToken" properties in our models to render as timestamp columns in the database. I'm doing this so that we can handle optimistic concurrency (when two or more people retrieve the same record and then attempt to save and overwrite one of the other person's changes).

    To enable Entity Framework Code First, open the Package Manager Console, set the default project to the "Data" project, and type the following:

    Package Manager Console - Enable Migrations

    This will add a new directory to your project, "Migrations," and a new class, "Configuration." The configuration class has a method that will help us seed the new database with some initial values. Replace the Seed method with this:

    protected override void Seed(Data.Context.RecreationContext context)
    {
        var facilities = new List<Facility>()
        {
            new Facility(){
                Name = "West Pavillion",
                SquareFeet = 12020,
                Reservations = new List<Reservation>()
            },
            new Facility(){
                Name = "East Pavillion",
                SquareFeet = 14500,
                Reservations = new List<Reservation>()
            },
            new Facility(){
                Name = "Bounce House",
                SquareFeet = 3000,
                Reservations = new List<Reservation>()
            },
            new Facility(){
                Name = "Botanical Garden",
                SquareFeet = 23123,
                Reservations = new List<Reservation>()
            }
        };
    
        facilities.ForEach(e => context.Facilities.AddOrUpdate(i => i.Name, e));
        context.SaveChanges();
    
        var guests = new List<Guest>()
        {
            new Guest(){
                FirstName = "Adam",
                LastName = "Jones",
                Reservations = new List<Reservation>()
            },
            new Guest(){
                FirstName = "Tiffany",
                LastName = "Bresnev",
                Reservations = new List<Reservation>()
            },
            new Guest(){
                FirstName = "Jackson",
                LastName = "Ackton",
                Reservations = new List<Reservation>()
            }
        };
    
        guests.ForEach(e => context.Guests.AddOrUpdate(i => i.LastName, e));
        context.SaveChanges();
    
        var reservations = new List<Reservation>()
        {
            new Reservation(){
                StartDateTime = new DateTime(2013, 1, 1),
                EndDateTime = new DateTime(2013, 1, 1),
                FacilityId = facilities.Single(p => p.Name == "West Pavillion").Id,
                GuestId = guests.Single(p => p.LastName == "Jones").Id
            },
            new Reservation(){
                StartDateTime = new DateTime(2013, 2, 1),
                EndDateTime = new DateTime(2013, 2, 1),
                FacilityId = facilities.Single(p => p.Name == "Bounce House").Id,
                GuestId = guests.Single(p => p.LastName == "Bresnev").Id
            },new Reservation(){
                StartDateTime = new DateTime(2013, 3, 1),
                EndDateTime = new DateTime(2013, 3, 1),
                FacilityId = facilities.Single(p => p.Name == "Botanical Garden").Id,
                GuestId = guests.Single(p => p.LastName == "Ackton").Id
            }
        };
    
        reservations.ForEach(e => context.Reservations.AddOrUpdate(i => new { i.StartDateTime, i.EndDateTime, i.FacilityId, i.GuestId }, e));
        context.SaveChanges();
    }
        

    When we tell Entity Framework to create the database, the Package Manager Console will look at our start-up project (the MVC project, in this case) and look for the connection string we specified in the RecreationContext class ("DefaultConnection"). I'm going to leave the connection string as the default and create a local database file in the App_Data folder. If you want the database to be created elsewhere, just update the connection string in the Web.config. Next, open the Package Manager Console and type the following:

    Package Manager Console - Initial Create

    This will create a class named "InitialCreate" that has the code necessary for Entity Framework to create the tables in our database. To create the database and generate the tables, type the following in the Package Manager Console:

    Package Manager Console - update-database

    If you open the Server Explorer -> DefaultConnection -> Tables, right-click on the Guest table, and select "Show Table Data," you should see the following:

    Server Explorer

    Let's make sure it works from our MVC application. Replace your HomeController with this:

    using Data.Context;
    using System.Linq;
    using System.Web.Mvc;
    
    namespace Recreation.Controllers
    {
        public class HomeController : Controller
        {
            private RecreationContext db = new RecreationContext();
    
            public ActionResult Index()
            {
                return View(db.Guests.ToList());
            }
    
            protected override void Dispose(bool disposing)
            {
                db.Dispose();
                base.Dispose(disposing);
            }
        }
    }
        

    Then modify your Views -> Home -> Index.cshtml file to look like this:

    @model List<Data.Models.Guest>
    @{
        ViewBag.Title = "Home";
    }
    
    <h2>@ViewBag.Title</h2>
    <ul>
        @foreach (var m in Model)
        {
            <li>@m.FirstName @m.LastName</li>
        }
    </ul>
        

    Run the application (F5) and you should see the three names we seeded to the database when it was created.

    Using the Unity IoC Container to Inject Dependencies in Your Controller

    First, install the Unity bootstrapper for ASP.NET MVC.

    NuGet Unity Bootstrapper

    This will also add the Unity NuGet package. The bootstrapper adds the necessary files in the MVC project's App_Start directory to initialize Unity and set the dependencies (the things you want to inject into other classes or methods). If you look in App_Start, you'll see two new files: UnityConfig.cs and UnityMvcActivator.cs. UnityMvcActivator uses WebActivatorEx to call the class's Start() method during application start. Of particular interest in the Start() method are the following lines:

    // TODO: Uncomment if you want to use PerRequestLifetimeManager
    // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
        

    Unity has what's called "lifetime managers" that manages how long any given object stays instantiated (alive). The The PerRequestLifetimeManager calls Dispose() on any object that makes use of the manager at the end of the HTTP request. We want to do this for our ObjectContext (RecreationContext) object so that it doesn't stay alive on the server, available for other requests. Make sure you uncomment the line so that we can safely dispose of any resources that implement IDisposable.

    The reason for my aforementiond head-banging was that I installed "Unity" and "Unity.MVC4" NuGet packages instead of the "Unity bootstrapper for ASP.NET MVC" package. The PerRequestLifetimeManager and UnityPerRequestHttpModule are only available in the bootstrapper package. I attempted to build several per-request lifetime managers but could never get them to call Dispose() on my managed services. It was ultimately the HttpModule that I was missing.

    Using the Inversion of Control, Repository, and Unit Of Work Patterns

    The Inversion of Control (IoC) pattern is all about resolving one type to another type. This resolution could be based on inheritance but most often you'll see it based on an interface. With this pattern, you develop against an interface and let the IoC container resolve it to a concrete implementation of that interface. You could have any number of implementations, it's up to the IoC container to create one for you. One of the ways it can do this is through Dependency Injection (DI). What you have is a consumer component (e.g. a MVC controller) that declares a dependency (or multiple dependencies) that it needs to get its job done. (Most commonly, you'll see this done through the constructor but some IoC frameworks allow you to inject through properties.) The IoC container creates an instance of a class that implements that given interface at runtime and "injects" it into that component. This pattern is somewhat like the Factory method pattern except that IoC relies on an external framework to operate (e.g. Unity, Windsor, Ninject, StructureMap). So IoC is really more of an architectural pattern as opposed to a design pattern.

    What we want now is an interface we can program against to get data from the Entity Framework ObjectContext (RecreationContext) we set up earlier. The interface should be generic enough that we can swap it out for another data access framework if we want but still robust enough to give us what we need to get things done in our controllers. The Repository pattern is ideal for this situation:

    A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes.

    So the repository is responsible for persisting our objects in memory but what about when it comes time to save changes to the collection(s) back to the database? That's where the Unit of Work pattern comes into play:

    A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

    Perfect!

    So that we can reuse our Repository and UnitOfWork classes, lets create a separate class library and call it something like "Core." Note that I'm placing it in the Projects directory and not the Recreation directory. That way I can easily reference the assembly when creating other projects. A "core" assembly is a great place to store commonly used code like extension methods, helper methods, and anything else you may want to use from project-to-project. (Ideally, you would place the IRepository and IUnitOfWork interfaces - along with their dependencies - in a "core" assembly and then create another assembly with an ORM-specific implementation but I'm going to combine them at this time for the sake of simplicity.)

    Core Class Library

    After you create the class library, install Entity Framework from the NuGet Package Manager then add these interfaces, classes, and enum:

    namespace Core
    {
        public enum EntityStatus : int
        {
            Added,
            Deleted,
            Detached,
            Modified,
            Unchanged
        }
    }
        
    using System;
    using System.Runtime.Serialization;
    
    namespace Core
    {
        public class ConcurrencyException : SystemException
        {
            public ConcurrencyException()
                : base()
            {
            }
    
            public ConcurrencyException(String message)
                : base(message)
            {
            }
    
            public ConcurrencyException(String message, Exception innerException)
                : base(message, innerException)
            {
            }
    
            public ConcurrencyException(SerializationInfo info, StreamingContext context)
                : base(info, context)
            {
            }
        }
    }
        
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace Core
    {
        public interface IRepository<T> : IDisposable where T : class
        {
            IQueryable<T> GetQueryable();
            IEnumerable<T> GetAll();
            IEnumerable<T> Find(Expression<Func<T, Boolean>> where);
            T Single(Expression<Func<T, Boolean>> where);
            T First(Expression<Func<T, Boolean>> where);
            void Delete(T entity);
            void Add(T entity);
            void Attach(T entity);
            void Attach(T entity, EntityStatus status);
        }
    }
        
    using System;
    
    namespace Core
    {
        public interface IUnitOfWork : IDisposable
        {
            void SaveChanges();
        }
    }
        
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity.Infrastructure;
    using System.Data.Objects;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace Core
    {
        public class Repository<T> : IRepository<T> where T : class
        {
            private readonly IObjectContextAdapter _ObjectContextAdapter;
            IObjectSet<T> _ObjectSet;
    
            public Repository(IObjectContextAdapter objectContextAdapter)
            {
                _ObjectContextAdapter = objectContextAdapter;
                _ObjectSet = objectContextAdapter.ObjectContext.CreateObjectSet<T>();
            }
    
            public IQueryable<T> GetQueryable()
            {
                return _ObjectSet;
            }
    
            public IEnumerable<T> GetAll()
            {
                return _ObjectSet.ToList();
            }
    
            public IEnumerable<T> Find(Expression<Func<T, Boolean>> where)
            {
                return _ObjectSet.Where(where);
            }
    
            public T Single(Expression<Func<T, Boolean>> where)
            {
                return _ObjectSet.Single(where);
            }
    
            public T First(Expression<Func<T, Boolean>> where)
            {
                return _ObjectSet.First(where);
            }
    
            public void Delete(T entity)
            {
                _ObjectSet.DeleteObject(entity);
            }
    
            public void Add(T entity)
            {
                _ObjectSet.AddObject(entity);
            }
    
            public void Attach(T entity)
            {
                Attach(entity, EntityStatus.Unchanged);
            }
    
            public void Attach(T entity, EntityStatus status)
            {
                _ObjectSet.Attach(entity);
                _ObjectContextAdapter.ObjectContext.ObjectStateManager.ChangeObjectState(entity, GetEntityState(status));
            }
    
            public void Dispose()
            {
                if (_ObjectContextAdapter != null)
                    _ObjectContextAdapter.ObjectContext.Dispose();
    
                GC.SuppressFinalize(this);
            }
    
            private EntityState GetEntityState(EntityStatus status)
            {
                switch (status)
                {
                    case EntityStatus.Added:
                        return EntityState.Added;
                    case EntityStatus.Deleted:
                        return EntityState.Deleted;
                    case EntityStatus.Detached:
                        return EntityState.Detached;
                    case EntityStatus.Modified:
                        return EntityState.Modified;
                    default:
                        return EntityState.Unchanged;
                }
            }
        }
    }
        
    using System;
    using System.Data;
    using System.Data.Entity.Infrastructure;
    
    namespace Core
    {
        public class UnitOfWork : IUnitOfWork
        {
            private readonly IObjectContextAdapter _ObjectContextAdapter;
    
            public UnitOfWork(IObjectContextAdapter objectContextAdapter)
            {
                _ObjectContextAdapter = objectContextAdapter;
            }
    
            public void SaveChanges()
            {
                try
                {
                    _ObjectContextAdapter.ObjectContext.SaveChanges();
                }
                catch (OptimisticConcurrencyException oce)
                {
                    throw new ConcurrencyException(oce.Message, oce.InnerException);
                }
                catch (DataException)
                {
                    throw;
                }
            }
    
            public void Dispose()
            {
                if (_ObjectContextAdapter != null)
                    _ObjectContextAdapter.ObjectContext.Dispose();
    
                GC.SuppressFinalize(this);
            }
        }
    }
        

    To implement the repository and unit of work into our MVC application, update the UnityConfig.cs file as follows:

    using Core;
    using Data.Context;
    using Microsoft.Practices.Unity;
    using System;
    using System.Data.Entity.Infrastructure;
    
    namespace Recreation.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;
            });
    
            /// <summary>
            /// Gets the configured Unity container.
            /// </summary>
            public static IUnityContainer GetConfiguredContainer()
            {
                return container.Value;
            }
            #endregion
    
            /// <summary>Registers the type mappings with the Unity container.</summary>
            /// <param name="container">The unity container to configure.</param>
            /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
            /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
            public static void RegisterTypes(IUnityContainer container)
            {
                // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
                // container.LoadConfiguration();
    
                // TODO: Register your types here
                container.RegisterType<IObjectContextAdapter, RecreationContext>(new PerRequestLifetimeManager());
                container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
                container.RegisterType<IUnitOfWork, UnitOfWork>();
            }
        }
    }
        

    What we're doing here is registering the interfaces and associating them with a concrete type in the RegisterTypes() method. Throughout the MVC application, we'll program against the interface but at runtime, Unity will inject a concrete instance of the interface.

    In the above code, the RecreationContext is instantiated per-request thanks to the PerRequestLifetimeManager. Here's the cool part: both Repository and UnitOfWork have constructors that accept IObjectContextAdapter. When the concrete implementations are instantiated, Unity injects the RecreationContext into them and then they get injected into the controller (see below). Both the Repository and the UnitOfWork then share the same context per request so that anything that happens in the Repository gets reflected in the UnitOfWork. How freaking cool is that?!

    Now we can update our HomeController to look like this:

    using Core;
    using Data.Models;
    using System.Web.Mvc;
    
    namespace Recreation.Controllers
    {
        public class HomeController : Controller
        {
            IRepository<Guest> _GuestRepository;
    
            public HomeController(IRepository<Guest> guestRepository)
            {
                _GuestRepository = guestRepository;
            }
    
            public ActionResult Index()
            {
                return View(_GuestRepository.GetAll());
            }
    
            protected override void Dispose(bool disposing)
            {
                _GuestRepository.Dispose();
                base.Dispose(disposing);
            }
        }
    }
        

    Now run the application (F5) and verify that the save values from the database are displayed in the view.

    When the controller is created, Unity inspects its constructor and compares the types in the signature with the registered types in its container. In this case, it found a generic IRepository<> interface and passed in an instance of the Repository<> class. By making the IRepository interface and Repository concrete implementation generic, we can create repositories for any number of Entity objects. You can inject as many items into a constructor as you want, too. Just add them to the constructor's method signature [e.g. public HomeController(IRepository<Guest> guestRepository, IRepository<Facility> facilityRepository, IRepository<Reservation> reservationRepository) and so on...]

    When you make changes through the repository, you're actually making changes to the Entities in the underlying ObjectContext. When it comes time to commit those changes back to the database, the Unit of Work we created earlier has that responsibility. Update your HomeController to this:

    using Core;
    using Data.Models;
    using System;
    using System.Web.Mvc;
    
    namespace Recreation.Controllers
    {
        public class HomeController : Controller
        {
            IRepository<Guest> _GuestRepository;
            IUnitOfWork _UnitOfWork;
    
            public HomeController(IRepository<Guest> guestRepository, IUnitOfWork unitOfWork)
            {
                _GuestRepository = guestRepository;
                _UnitOfWork = unitOfWork;
            }
    
            public ActionResult Index()
            {
                return View(_GuestRepository.GetAll());
            }
    
            public ActionResult Edit()
            {
                return View(_GuestRepository.First(g => g.LastName == "Bresnev"));
            }
    
            [HttpPost]
            public ActionResult Edit(Guest guest)
            {
                _GuestRepository.Attach(guest, EntityStatus.Modified);
    
                if (ModelState.IsValid)
                {
                    try
                    {
                        _UnitOfWork.SaveChanges();
                    }
                    catch (ConcurrencyException)
                    {
                        ModelState.AddModelError(String.Empty, "The record you attempted to edit was modified by another user after you got the original value. Your edit operation was canceled. If you still want to edit this record, save it again.");
                    }
                    catch (Exception)
                    {
                        ModelState.AddModelError(String.Empty, "Unable to save changes. Please try again.");
                    }
                }
    
                return View(guest);
            }
    
            protected override void Dispose(bool disposing)
            {
                _GuestRepository.Dispose();
                _UnitOfWork.Dispose();
                base.Dispose(disposing);
            }
        }
    }
        

    Right-click within the Edit() method and add a View. Change the Edit.cshtml view to look like this:

    @model Data.Models.Guest
    @{
        ViewBag.Title = "Edit";
    }
    
    <h2>@ViewBag.Title</h2>
    <ul>
        <li>@Model.FirstName @Model.LastName</li>
    </ul>
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
    
        @Html.TextBoxFor(m => m.FirstName);
        
        @Html.HiddenFor(m => m.Id)
        @Html.HiddenFor(m => m.LastName)
        @Html.HiddenFor(m => m.ConcurrencyToken)
        <input type="submit" value="Change First Name" />
    }
        

    I realize this is a pretty lame example but I just wanted to get the idea across.

    The reason for creating my own ConcurrencyException and managing my own Entity state/status is that I didn't want to create any dependencies on Entity Framework in the interfaces. I'm not sure about other ORM's but I can imagine that there are ways on others to manage concurrency exceptions or the status change of an object. The point, though, is to make an interface that's as neutral as possible to a concrete implementation so that you can change the concrete implementation without having to change the interface and the code depending on that interface.

    Please let me know if you have any suggestions on how to make this better!

    You can get the code here.

  3. Handling Inheritance Using Table-Per-Type in Entity Framework Code First

    There are a few ways to handle persisting inheritance with Entity Framework 5 Code First. Table-Per-Hierarchy and Table-Per-Type are the most common. TPH seems to be the most prevalent but I'm not a huge fan. With TPH, only one table is created to handle the parent type and it's child types.

    For example, suppose you had a class named "Person" and two inherited classes named "Instructor" and "Student". "Person" has two properties: "FirstName" and "LastName." "Instructor" as a property for "HireDate." "Student" has a property for "EnrollmentDate." When Entity Framework creates the database for this model, by default it creates a single table with columns for all of the class properties. "HireDate" and "EnrollmentDate" are nullable such that "Instructor" records would have a value for "HireDate" but "EnrollmentDate" would be null whereas "Student" records would have a value for "EnrollmentDate" but "HireDate" would be null. To distinguish among the different sub-types, there's a "Discriminator" column added to the table that holds the name of the sub-type (e.g. "Instructor" and "Student"). The "Discriminator" column denormalizes the data and would likely irritate any DBA's in your organization.

    When you set up your classes to use Table-Per-Type, three tables are created: "Person," "Instructor," and "Student" with one-to-one relationships. You avoid the denormalization but, supposedly, there's a performance cost on the Entity Framework side because you have to join the tables when you query them. Personally, I'd rather avoid the denormalization - especially for tables that are expected to grow to any great number of rows.

    Here are the classes:

    public abstract class Person
    {
        [Key]
        public Int32 Id { get; set; }
        public String FirstName { get; set; }
        public String LastName { get; set; }
    }
    
    public class Instructor : Person
    {
        public DateTime HireDate { get; set; }
    }
    
    public class Student : Person
    {
        public DateTime EnrollmentDate { get; set; }
    }
        

    I prefer to use the Fluent API to specify how the tables are created as opposed to using attributes in the POCO classes. To get EF to create the separate tables, use the .ToTable(tableName) method:

    public class UniversityContext : DbContext
    {
        public DbSet<Person> People { set; get; }
        public DbSet<Instructor> Instructors { set; get; }
        public DbSet<Student> Students { set; get; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    
            modelBuilder.Entity<Instructor>().ToTable("Instructor");
            modelBuilder.Entity<Student>().ToTable("Student");
        }
    }