A day with .Net

My day to day experince in .net

Archive for the ‘Entity Framework’ Category

Design an MVC application Using Enity Framework Repository Pattern, Unit Of Work Pattern and Dependency Injection

Posted by vivekcek on June 10, 2013

In this post, I am going to present how to design an MVC application Using Enity Framework Repository Pattern, Unit Of Work Pattern and Dependency Injection.

I hope the reader is aware of the basics of MVC, Entity Framework, Repository Pattern, Unit Of Work Pattern and Dependency Injection. Because in this post, i am only concentrating on practical implementation.

What is Entity Framework?

Entity Framework (EF) is an object-relational mapper that enables .NET developers to work with relational data using domain-specific objects.It eliminates the need for most of the data-access code that developers usually need to write.

The Repository and Unit of Work Patterns?

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store.

Creating a repository class for each entity type could result in a lot of redundant code, and it could result in partial updates. For example, suppose you have to update two different entity types as part of the same transaction. If each uses a separate database context instance, one might succeed and the other might fail. One way to minimize redundant code is to use a generic repository, and one way to ensure that all repositories use the same database context (and thus coordinate all updates) is to use a unit of work class.

The unit of work class coordinates the work of multiple repositories by creating a single database context class shared by all of them.

2

Why Need to Inject Controller Dependency?

In real life application development, you will see almost all ASP.NET MVC applications are needed to inject its dependent component. You can create component directly inside the controller instead of inject them. In that case the controller will be strongly coupled on those components. If any component’s implementation is changed or new version of that component is released then you must change controller class itself.

End Of Theory

The example i am using is a small Blog Engine concept, Which include 3 domain objects ‘Blog’, ‘Post’ and ‘Comment’.

Look at the solution structure. Please note the Class library names.

1

1. Create 3 domain classes ‘Blog’, ‘Post’, ‘Comment’ in ‘BlogEngine.Model’ Library. Don’t forgot to install Entity Framework Nuget Package. Also do look at the namespaces.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
namespace BlogEngine.Model
{
    public class Blog
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int BlogId { set; get; }

        [Required,StringLength(500)]
        public string BlogName { set; get; }

        public virtual ICollection<Post> Posts { get; set; }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace BlogEngine.Model
{
    public class Post
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int PostId { get; set; }

        [Required]
        public string Title { get; set; }

        [Required]
        public string Content { get; set; }

       
        public int BlogId { get; set; }

        [ForeignKey("BlogId")]
        public Blog Blog { get; set; }

        public virtual ICollection<Comment> Comments { get; set; }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace BlogEngine.Model
{
    public class Comment
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CommentId { get; set; }

        [Required]
        public string Content { get; set; }
    }
}

2. Create a Generic Repository Interface ‘IRepository’ in ‘BlogEngine.Data.Contract’ Library.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace BlogEngine.Data.Contract
{
    public interface IRepository<T> where T : class
    {
        IQueryable<T> GetAll();
        IQueryable<T> Find(Expression<Func<T, bool>> predicate);
        T GetById(int id);
        void Remove(T entity);
        void Add(T newEntity);
    }
}

3. Implement this ‘IRepository’ interface in ‘BlogEngine.Data’ Library as ‘BlogEngineRepository’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BlogEngine.Data.Contract;
using System.Data.Entity;

namespace BlogEngine.Data
{
    public class BlogEngineRepository<T> : IRepository<T> where T : class
    {
        protected DbContext DbContext { get; set; }
        protected DbSet<T> DbSet { get; set; }

        public BlogEngineRepository(DbContext dbContext)
        {
            if (dbContext == null)
            {
                throw new ArgumentNullException("dbContext");
            }
            else
            {
                DbContext = dbContext;
                DbSet = DbContext.Set<T>();
            }
        }

        public IQueryable<T> GetAll()
        {
            return DbSet;
        }

        public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            return DbSet.Where(predicate);
        }

        public T GetById(int id)
        {
            return DbSet.Find(id);
        }

        public void Remove(T entity)
        {
            DbSet.Remove(entity);
        }

        public void Add(T newEntity)
        {
            DbSet.Add(newEntity);
        }
    }
}

4. Create a DbContext class named ‘BlogEngineDbContext’ in ‘BlogEngine.Data’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using BlogEngine.Model;

namespace BlogEngine.Data
{
    public class BlogEngineDbContext:DbContext
    {

        public BlogEngineDbContext()
            : base("name=BlogEngineDbContext")
        {

        }
        public DbSet<Blog> Blogs { get; set; }
    }
}

5. Create a Unit Of Work Interface named ‘IBlogEngineUnitOfWork’ under ‘BlogEngine.Data.Contract’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BlogEngine.Model;

namespace BlogEngine.Data.Contract
{
    public interface IBlogEngineUnitOfWork
    {
        void Commit();
        IRepository<Blog> Blogs { get; }
    }
}

6. Implement ‘IBlogEngineUnitOfWork’ in ‘BlogEngine.Data’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BlogEngine.Data.Contract;
using BlogEngine.Model;

namespace BlogEngine.Data
{
    public class BlogEngineUnitOfWork : IBlogEngineUnitOfWork, IDisposable
    {
        private BlogEngineDbContext DbContext = null;

        public BlogEngineUnitOfWork()
        {
            DbContext = new BlogEngineDbContext();
        }
        
        public void Commit()
        {
            DbContext.SaveChanges();
        }

        public IRepository<Model.Blog> Blogs
        {
            get { return new BlogEngineRepository<Blog>(DbContext); }
        }

        public void Dispose()
        {
            DbContext.Dispose();
        }
    }
}

7. Now in our MVC 4 Web Project ‘BlogEngine.Web’ add a Nuget Package named ‘StructureMap’

3

8. Now in Web project, create a folder named Infrastructure and add 2 classes ‘BlogEngineControllerFactory’ and ‘BootStrapper’

4

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StructureMap;
namespace BlogEngine.Web.Infrastructure
{
    public class BlogEngineControllerFactory:DefaultControllerFactory
    {
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            return ObjectFactory.GetInstance(controllerType) as IController;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using StructureMap;
using BlogEngine.Data.Contract;
using BlogEngine.Data;
using StructureMap.Configuration.DSL;

namespace BlogEngine.Web.Infrastructure
{
    public class BootStrapper
    {
        public static void ConfigureDependencies()
        {
            ObjectFactory.Initialize(x => x.AddRegistry<ControllerRegistry>());
        }
        public class ControllerRegistry : Registry
        {
            public ControllerRegistry()
            {
                For<IBlogEngineUnitOfWork>().Use<BlogEngineUnitOfWork>();
            }
        }
    }
}

9. Now in Global.asax under Application_Start() add the below code.

ControllerBuilder.Current.SetControllerFactory(new BlogEngineControllerFactory());
BootStrapper.ConfigureDependencies();

10. Now add a HomeController and View. The controller code is given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BlogEngine.Data.Contract;
using BlogEngine.Model;

namespace BlogEngine.UI.Web.Controllers
{
    public class HomeController : Controller
    {
        private IBlogEngineUnitOfWork UoW = null;

        public HomeController(IBlogEngineUnitOfWork _UoW)
        {
            UoW = _UoW;
        }
        
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(Blog blog)
        {
            UoW.Blogs.Add(blog);
            UoW.Commit();
            return RedirectToAction("Index");    
        }

        public ActionResult List()
        {
            return View(UoW.Blogs.GetAll());
        }

    }
}

11. A complete Solution Structure Is Given below.

5

Posted in Entity Framework, MVC | 1 Comment »

Seed database on application start EF code first

Posted by vivekcek on May 30, 2013

Create Your Context Class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
 
namespace ContosoUniversity.Models
{
    public class SchoolContext : DbContext
    {
       
    }
}

Create a context initializer class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
    public class SchoolInitializer : DropCreateDatabaseIfModelChanges<SchoolContext>
    {
        protected override void Seed(SchoolContext context)
        {

        }
    }
}

Add this code under Application_Start(). Please remove this code in production.

Database.SetInitializer<SchoolContext>(new SchoolInitializer());

Posted in Entity Framework | Leave a Comment »

Remove Pluralizing TableName Entity Framework Code First

Posted by vivekcek on May 30, 2013

Try this code. Look at the namespaces used.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ContosoUniversity.Models
{
    public class SchoolContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}

Posted in Entity Framework | Leave a Comment »

Create database in App_Data folder Entity Frame Work Code First.

Posted by vivekcek on May 30, 2013

If you want EF to create your database under App_Data folder.

First set your connection string as below. Please note that the name should be same as your DbContext class name.

<add name="AppDB"
           connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|mydatabase.mdf;User Instance=true;Initial Catalog=myDataBase"
           providerName="System.Data.SqlClient" />

Example of context file.

public class AppDB : DbContext
    {
        public AppDB()
            : base("name=AppDB")
        {
            
        }
    }

Posted in Entity Framework, MVC | Leave a Comment »