Monthly Archives: November 2011

Using Entity framework features Part 2

In the previous post, I talked about the advantages of using code first method and EF4.1/2 , created a sample model in a domain project, then added DataAccess project for direct use in an MVC project. Now I want to use data access in my service layer. How?

Recently i heard about repository pattern! So I’m implementing this in a new project and then i’ll complete the domain layer:

 

Before implementing the repository pattern i need an interface to access the DataAccess layer, So i create IDbContext interface in the Infrastructure library project:

public interface IDbContext

    {
        IDbSet Set() where T : class;

        Database Db { get; }

        int SaveChanges();
    }

Now i add a Repository pattern to the project:

First i use an interface repository in Infrastructure project:

public interface IRepository where T : class
{
        ///
 /// Create New Instance /// 

 T NewEntityInstance(); ///
 /// Inserts an item /// 

 void Add(T item); ///
 /// Deletes an item /// 

 void Remove(T item); ///
 /// Get an item matching to prediate /// 

 T Get(Funcpredicate); ///
 /// Get Count of items matching to predicate /// 

 int GetCount(Funcpredicate); ///
 /// Get IEnumerable object matching to predicate /// 

 IEnumerableGetAll(Funcpredicate); ///
 /// Get IEnumerable object matching to predicate,start index and count /// 

 IEnumerableGetAll(Funcpredicate, int start, int count); ///
 /// Saves the pending changes back into the DataContext. /// 

 void Save();
}

And then put it in DataAccess project:

    public class Repository : IRepository where T : class
    {
        protected IDbContext _Context;
        protected IDbSet _DbSet;

        public Repository(IDbContext context)
        {
            _Context = context;
            _DbSet = _Context.Set();
        }

        public T NewEntityInstance()
        {
            return _DbSet.Create();
        }

        public void Add(T entity)
        {
            _DbSet.Add(entity);
        }

        public virtual IQueryable GetAll()
        {
            return _DbSet.AsQueryable();
        }

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

        public T Get(Func predicate)
        {
            return _DbSet.FirstOrDefault(predicate);
        }

        public int GetCount(Func predicate)
        {
            return _DbSet.Count(predicate);
        }

        public IEnumerable GetAll(Func predicate)
        {
            return _DbSet.Where(predicate);
        }

        public IEnumerable GetAll(Func predicate, int start, int count)
        {
            return _DbSet.Where(predicate).Skip(start).Take(count);
        }

        public void Save()
        {
            try
            {
                _Context.SaveChanges();
            }
            catch (DbEntityValidationException e)
            {
                var s = e.EntityValidationErrors.ToList();
                throw;
            }
        }

        public IEnumerable GetQuery(string queryString, Func predicate = null) where K : class
        {
            if (predicate != null)
                return _Context.Db.SqlQuery(queryString).Where(predicate);
            return _Context.Db.SqlQuery(queryString);

        }
    }

Good, Service classes are ready to be used in Controllers and action methods.

How to create a service:

for example i wrote a simple service named MemberManager:

using System;
using System.Collections.Generic;
using Arash.Membership.Model;

namespace Arash.Core
{
    public interface IMemberManager
    {
        Member MakeInstance();

        void Add(Member entity);

        void Edit(Member entity);

        void Remove(Member entity);

        int GetCount(Func predicate = null);

        Member Get(Func predicate = null);

        IEnumerable GetAll(Func predicate = null, int start = 0, int count = 6);

        Member Authenticate(string username, string password);
    }
}

implemented Member service class:

using System;
using System.Collections.Generic;
using Arash.Membership.Model;
using Arash.Utility.Common;
using Paradiso.Infrastructure.Data;
using Arash.Infrastructure.Data;

namespace Arash.Core.Manager
{
    public class MemberManager : IMemberManager
    {
        private IRepository _repository;

        public MemberManager(IRepository repository)
        {
            _repository = repository;
        }

        public Member MakeInstance()
        {
            return _repository.NewEntityInstance();
        }

        public void Add(Member entity)
        {
            _repository.Add(entity);
            _repository.Save();
        }

        public void Edit(Member entity)
        {
            _repository.Save();
        }

        public void Remove(Member entity)
        {
            _repository.Remove(entity);
            _repository.Save();
        }

        public int GetCount(Func predicate = null)
        {
            return predicate == null
                ? _repository.GetCount(p => true)
                : _repository.GetCount(predicate);
        }

        public Member Get(Func predicate = null)
        {
            return predicate == null
                ? _repository.Get(p => true)
                : _repository.Get(predicate);
        }

        public IEnumerable GetAll(Func predicate = null, int start = 0, int count = 6)
        {
            return predicate == null
                 ? _repository.GetAll(p => true)
                 : start == 0
                     ? _repository.GetAll(predicate)
                     : _repository.GetAll(predicate, start, count);
        }

        public Member Authenticate(string username, string password)
        {
            var entity = _repository.Get(p => p.Username == username);

            if (entity == null)
                return null;

            var passwordHash = PasswordGenerator.GetHashPassword(password);

            if (!string.Equals(passwordHash, password))
                return null;

            return entity;
        }
    }
}

Conclusion:

We learned how to implement some layers in n-layer architecture. Ofcourse you can download source codes of posts part1 and 2 from github