Friday, 6 January 2017

Create a Dependency injection using the NInject for Repository pattern in ASP.NET MVC

In this post we are going to see how to create a Dependency injection using NInject for Repository pattern in ASP.NET MVC

Right the soultion explorer and click the Manage Nuget packages, Then search for Ninject for MVC , then click install, This will install the Ninject in MVC project. This will create the NinjectWebCommon.cs File.

Inside this class we have method named RegisterServices, where we have to register the instances using the Bind method and To, For create the dependency injection we have to inject through constructor of a controller,Here we are using the UnitOfWork in Repository Pattern.



    public interface IUnitOfWork:IDisposable
    {
        IEmployeeRepository Employees { get; }

        IDepartmentRepository Departments { get; }

        ITaskRepository Tasks { get; }

        int Save();

    }


    public class UnitOfWork : IUnitOfWork
    {
        private DbContext context;
   
        public UnitOfWork(CompanyDbContext context)
        {
            this.context = context;
            Departments = new DepartmentRepository(context);
            Employees = new EmployeeRepository(context);
            Tasks = new TaskRepository(context);
        }

        public IDepartmentRepository Departments
        {
            get; private set;
        }

        public IEmployeeRepository Employees
        {
            get; private set;
        }

        public ITaskRepository Tasks
         {
            get; private set;
        }

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

        public int Save()
        {
            return context.SaveChanges();
        }


    }



Code First Approach

    public class Employee
    {
        public Employee()
        {
            Tasks = new List<Task>();
        }

        public string Name { setget; }

        public int Id { setget; }

        public int Contact { setget; }

        public string Address { setget; }

        public int Salary { setget; }

        public int DepartmentId { setget; }

        [ForeignKey("DepartmentId")]
        public virtual Department Department { setget; }

        public virtual ICollection<Task> Tasks { setget; }


    }

    public class Department
    {
        public int Id { setget; }

        public string Name { setget; }
       
        public virtual ICollection<Employee> Employees { setget; }

    }


    public class Task
    {
        public int Id { setget; }

        public string Name { setget; }

        public string Description { setget; }

        public int EmployeeId { setget; }

        [ForeignKey("EmployeeId")]
        public virtual Employee Employee { setget; }

    }


For the above models we have to create the EntityDbContext

    public class CompanyDbInitializer :            
           DropCreateDatabaseIfModelChanges<CompanyDbContext>
    {
        protected override void Seed(CompanyDbContext context)
        {               
            base.Seed(context);
        }
    }


    public class CompanyDbContext:DbContext
    {
        public CompanyDbContext():base("companyConnection")
        {
            this.Configuration.AutoDetectChangesEnabled = true;
            this.Configuration.LazyLoadingEnabled = true;
            Database.SetInitializer(new CompanyDbInitializer());
        }

        public DbSet<Employee> Employees { setget; }

        public DbSet<Department> Departments { setget; }

        public DbSet<Task> Tasks { setget; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }

    }


Connection String in web.config
  <connectionStrings>
    <add name="companyConnection" 
         connectionString="Server=SQLEXPRESS;Database=EFDB;Integrated Security=true;"                 providerName="System.Data.SqlClient" />

  </connectionStrings>



Now we have to create a Generic Repository for the Context, Then we have to derive it for all respository. The Generic Repository will contain common operation like Get, GetAll, Fetch, Insert, InsertCollection, Update, Delete, DeleteCollection, SingleOrDefault, FirstOrDefault

    public interface IRepository<T>
    {
        T Get(int id);

        IEnumerable<T> GetAll();

        IEnumerable<T> Fetch(Expression<Func<Tbool>> predicate);

        void Insert(T obj);

        void InsertCollection(IEnumerable<T> collection);

        T update(T obj);

        void Delete(T obj);

        void DeleteCollection(IEnumerable<T> collection);

        T SingleOrDefault(Expression<Func<Tbool>> predicate);

        T FirstOrDefault(Expression<Func<Tbool>> predicate);


    }


    public class Repository<T> : IRepository<Twhere T : class
    {
        protected DbContext context;

        public Repository(DbContext context)
        {
            this.context = context;
        }

        public void Delete(T obj)
        {
            context.Set<T>().Remove(obj);           
        }

        public void DeleteCollection(IEnumerable<T> collection)
        {
            context.Set<T>().RemoveRange(collection);
        }

        public IEnumerable<T> Fetch(Expression<Func<Tbool>> predicate)
        {
            return context.Set<T>().Where(predicate);
        }

        public T FirstOrDefault(Expression<Func<Tbool>> predicate)
        {
            return context.Set<T>().FirstOrDefault(predicate);
        }

        public T Get(int id)
        {
            return context.Set<T>().Find(id);
        }

        public IEnumerable<T> GetAll()
        {
            return context.Set<T>().ToList();
        }

        public void Insert(T obj)
        {
            context.Set<T>().Add(obj);
        }

        public void InsertCollection(IEnumerable<T> collection)
        {
            context.Set<T>().AddRange(collection);
        }

        public T SingleOrDefault(Expression<Func<Tbool>> predicate)
        {
            return context.Set<T>().SingleOrDefault(predicate);
        }

        public T update(T obj)
        {
            context.Entry<T>(obj).State = EntityState.Modified;
            return obj;
        }

    }


Now we are going to create Repository for all Entities.

    public interface IEmployeeRepository : IRepository<Employee>
    {
        IEnumerable<Task> GetTasks(int EmployeeId);
    }

    public interface IDepartmentRepository : IRepository<Department>
    {
        IEnumerable<Employee> GetEmployees(int departmentid);
    }

    public interface ITaskRepository : IRepository<Task>
    {
        Employee GetEmployee(int taskid);

    }


In each Repository we are adding individual methods which are needed for that repositories.
Now we are going to implement the Repository,

    public class EmployeeRepository : Repository<Employee>, IEmployeeRepository
    {
        public EmployeeRepository(DbContext context):base(context)
        {

        }

        public IEnumerable<Task> GetTasks(int EmployeeId)
        {
            return this.Context.Employees.Find(EmployeeId).Tasks;
        }

        public CompanyDbContext Context
        {
            get
            {
                return this.context as CompanyDbContext;
            }
        }

    }



    public class DepartmentRepository : Repository<Department>, IDepartmentRepository
    {
        public DepartmentRepository(DbContext context):base(context)
        {

        }
        public IEnumerable<Employee> GetEmployees(int departmentid)
        {
            return Context.Departments.Find(departmentid).Employees;
        }

        public CompanyDbContext Context
        {
            get { return context as CompanyDbContext; }
        }
    }



    public class TaskRepository : Repository<Task>, ITaskRepository
    {
        public TaskRepository(DbContext context):base(context)
        {

        }
        public Employee GetEmployee(int taskid)
        {
            return Context.Tasks.Find(taskid).Employee;
        }

        public CompanyDbContext Context
        {
            get
            {
                return context as CompanyDbContext;
            }
        }
    }


Inside the controller you can see now that the constructor have an injection of interface IUnitOfWork, which is a dependency injection need to resolve when controller loads,Now this can be achieve by NInject, 


    public class HomeController : Controller
    {
        IUnitOfWork repo;

        public HomeController(IUnitOfWork work)
        {
            repo = work;
        }
            
        public ActionResult Index()
        {
          
            Employee empl = repo.Employees.Fetch(x => x.Id == 3).FirstOrDefault();
            empl.Name = "Rajesh";
            repo.Employees.update(empl);
            repo.Save();

            repo.Employees.Delete(empl);
            repo.Save();


            Employee emp = new Employee() { Id = 102,
Name = "Suresh", DepartmentId = 1 };
            repo.Employees.Insert(emp);
            repo.Save();

            return View(empl);
         
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }



NinjectWebCommon.cs  inside the RegisterServices method we are going to register the interface and there instances. 

UnitOfWork instance have an parameter for an constructor , this can be passed by WithConstructor Argument where we have to specify the parameter name and instance



   private static void RegisterServices(IKernel kernel)
   {           
            kernel.Bind<IUnitOfWork>().To<UnitOfWork>()
                   .WithConstructorArgument("context",new CompanyDbContext());
   }




Now if you load the page, the instance of UnitOfWork is injected in to the controller constructor








From this post you can see how to create a Dependency injection using Ninject for Repository pattern in ASP.NET MVC.




No comments:

Post a Comment