Thursday, 12 January 2017

Web Api Architecture with Dependency Injection And Unit Of Work and Repository Class

First Create a Empty  Webapplication. Choose MVC and Web Api.
Design Style is:


 Create A solution Structure look like this.
1.       BusinessEntites   (Where Entity framework Model Generator You Will add).
2.       Business Services  (Where Interface and Class will Implements).
3.       DataModel   (where Entity Frame you will add).



 4.    Next you add Entity Framework Database First.
Next Go to Business Entites. Add entity Framework DbConext Generator 6.


Next go to Data Model and Delete Datamodel.tt.
Next Go to Business Entites Model and open model.tt file. Set dataaccesslayer edmx file path. Sceen is.


Next go to context.cs file give business entites reference into datamodel.
And add Namespace : Using BusinessEntites.


Next Go to Business Service.
Add one interface which name is ITestDepartment and one class file where we implements .
Add businessReference into Business service.



Write this code in  your Interface
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BusinessEntities;

namespace BusinessServices
{
    public interface ITestDepartment
    {
        IEnumerable<TestDepartment> GetAllTestDepartments();
        TestDepartment GetTestDepartmentById(int EmployeeId);
        TestDepartment InsertDepartment(TestDepartment TestDepartmentEntity);
        TestDepartment UpdateTestDepartment(int EmployeeId, TestDepartment TestDepartmentEntity);
        bool DeleteTestDepartment(int EmployeeId);

    }
}


Next Implement tis interface in TextDepartment class file.
That are

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BusinessServices
{
      public class TestDepartmentService : ITestDepartmentService
   {
      private readonly UnitOfWork _unitOfWork;
        /// <summary>
        /// Public constructor.
        /// </summary>
        public TestDepartmentService()
        {
            _unitOfWork = new UnitOfWork();
        }

        /// <summary>
        /// Fetches all the Citys.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<TestDepartment> GetAllTestDepartments()
        {
            var citys = _unitOfWork.TestEmployeeRepository.GetAll().ToList();
            if (citys.Any())
            {
                //Mapper.CreateMap<TestEmployee, TestEmployee>();
                //var testEmployeeModel = Mapper.Map<List<TestEmployee>, List<TestEmployee>>(citys);
                return citys;
            }
            return null;
        }

        public TestDepartment GetTestDepartmentById(int EmployeeId)
        {
            var testEmployee = _unitOfWork.TestEmployeeRepository.GetByID(EmployeeId);
            if (testEmployee != null)
            {
                //Mapper.CreateMap<TestEmployee, TestEmployee>();
                //var testEmployeeModel = Mapper.Map<TestEmployee, TestEmployee>(testEmployee);
                return testEmployee;
            }
            return null;
        }
        /// <summary>
        /// Creates a City
        /// </summary>
        /// <param name="cityEntity"></param>
        /// <returns></returns>

        public TestDepartment InsertDepartment(TestDepartment TestDepartmentEntity)
        {
           using (var scope = new TransactionScope())
            {
                var testdepartment = new TestDepartment
                {
                    DepartmentId = TestDepartmentEntity. DepartmentId,
                    DepartmentName = TestDepartmentEntity. DepartmentName,
                    DepartmentAddress = TestDepartmentEntity. DepartmentAddress
                };
                _unitOfWork.TestEmployeeRepository.Insert(testEmployee);
                _unitOfWork.Save();
                scope.Complete();
                return TestDepartmentEntity;
            }
        }

         /// <summary>
        /// Updates a department
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="productEntity"></param>
        /// <returns></returns>
        public TestDepartment UpdateTestDepartment(int EmployeeId, TestDepartment TestDepartmentEntity)
        {
            TestDepartment testdept= null;
            //var success = false;
            if (TestDepartmentEntity != null)
            {
                using (var scope = new TransactionScope())
                {
                    testdept = _unitOfWork.TestEmployeeRepository.GetByID(EmployeeId);
                    if (testdept != null)
                    {
                        TestDepartmentEntity.DepartmentId = TestDepartmentEntity.DepartmentId;
                        TestDepartmentEntity.DepartmentName = TestDepartmentEntity.DepartmentName;
                        TestDepartmentEntity.DepartmentCode = TestDepartmentEntity.DepartmentCode;
                        _unitOfWork.TestEmployeeRepository.Update(testdept);
                        _unitOfWork.Save();
                        scope.Complete();
                        //success = true;
                    }
                }
            }
            return testdept;
        }
      

        /// <summary>
        /// Deletes a particular Department
        /// </summary>
        /// <param name="CityId"></param>
        /// <returns></returns>
        public bool DeleteTestDepartment(int EmployeeId)
        {
            var success = false;
            if (EmployeeId >= 0)
            {
                using (var scope = new TransactionScope())
                {
                    var testdepartment = _unitOfWork.TestEmployeeRepository.GetByID(EmployeeId);
                    if (testdepartment != null)
                    {
                        _unitOfWork.TestEmployeeRepository.Delete(testdepartment);
                        _unitOfWork.Save();
                        scope.Complete();
                        success = true;
                    }
                }
            }
            return success;
        }
    }
}
That are implement in After
Next go To Datamodel Layer
Craete 2 Folder in DataModel
1.       GenericRepository
2.       UnitOfWork
For Generic Reprosotory we add  a class file which Design is


Add This Code in Generic Reprosotory
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataModel.GenericRepository
{
    /// <summary>
    /// Generic Repository class for Entity Operations
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class GenericRepository<TEntity> where TEntity : class
    {
        #region Private member variables...
        internal AdminEntitiesModel Context;
        internal DbSet<TEntity> DbSet;
        #endregion

        #region Public Constructor...
        /// <summary>
        /// Public Constructor,initializes privately declared local variables.
        /// </summary>
        /// <param name="context"></param>
        public GenericRepository(AdminEntitiesModel context)
        {
            this.Context = context;
            this.DbSet = context.Set<TEntity>();
        }
        #endregion

        #region Public member methods...

        /// <summary>
        /// generic Get method for Entities
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<TEntity> Get()
        {
            IQueryable<TEntity> query = DbSet;
            return query.ToList();
        }

        /// <summary>
        /// Generic get method on the basis of id for Entities.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual TEntity GetByID(object id)
        {
            return DbSet.Find(id);
        }

        /// <summary>
        /// generic Insert method for the entities
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Insert(TEntity entity)
        {
            DbSet.Add(entity);
        }

        /// <summary>
        /// Generic Delete method for the entities
        /// </summary>
        /// <param name="id"></param>
        public virtual void Delete(object id)
        {
            TEntity entityToDelete = DbSet.Find(id);
            Delete(entityToDelete);
        }

        /// <summary>
        /// Generic Delete method for the entities
        /// </summary>
        /// <param name="entityToDelete"></param>
        public virtual void Delete(TEntity entityToDelete)
        {
            if (Context.Entry(entityToDelete).State == EntityState.Detached)
            {
                DbSet.Attach(entityToDelete);
            }
            DbSet.Remove(entityToDelete);
        }

        /// <summary>
        /// Generic update method for the entities
        /// </summary>
        /// <param name="entityToUpdate"></param>
        public virtual void Update(TEntity entityToUpdate)
        {
            DbSet.Attach(entityToUpdate);
            Context.Entry(entityToUpdate).State = EntityState.Modified;
        }

        /// <summary>
        /// generic method to get many record on the basis of a condition.
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual IEnumerable<TEntity> GetMany(Func<TEntity, bool> where)
        {
            return DbSet.Where(where).ToList();
        }

        /// <summary>
        /// generic method to get many record on the basis of a condition but query able.
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual IQueryable<TEntity> GetManyQueryable(Func<TEntity, bool> where)
        {
            return DbSet.Where(where).AsQueryable();
        }

        /// <summary>
        /// generic get method , fetches data for the entities on the basis of condition.
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public TEntity Get(Func<TEntity, Boolean> where)
        {
            return DbSet.Where(where).FirstOrDefault<TEntity>();
        }

        /// <summary>
        /// generic delete method , deletes data for the entities on the basis of condition.
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public void Delete(Func<TEntity, Boolean> where)
        {
            IQueryable<TEntity> objects = DbSet.Where<TEntity>(where).AsQueryable();
            foreach (TEntity obj in objects)
                DbSet.Remove(obj);
        }

        /// <summary>
        /// generic method to fetch all the records from db
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<TEntity> GetAll()
        {
            return DbSet.ToList();
        }

        /// <summary>
        /// Inclue multiple
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="include"></param>
        /// <returns></returns>
        public IQueryable<TEntity> GetWithInclude(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate, params string[] include)
        {
            IQueryable<TEntity> query = this.DbSet;
            query = include.Aggregate(query, (current, inc) => current.Include(inc));
            return query.Where(predicate);
        }

        /// <summary>
        /// Generic method to check if entity exists
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        public bool Exists(object primaryKey)
        {
            return DbSet.Find(primaryKey) != null;
        }

        /// <summary>
        /// Gets a single record by the specified criteria (usually the unique identifier)
        /// </summary>
        /// <param name="predicate">Criteria to match on</param>
        /// <returns>A single record that matches the specified criteria</returns>
        public TEntity GetSingle(Func<TEntity, bool> predicate)
        {
            return DbSet.Single<TEntity>(predicate);
        }

        /// <summary>
        /// The first record matching the specified criteria
        /// </summary>
        /// <param name="predicate">Criteria to match on</param>
        /// <returns>A single record containing the first record matching the specified criteria</returns>
        public TEntity GetFirst(Func<TEntity, bool> predicate)
        {
            return DbSet.First<TEntity>(predicate);
        }


        #endregion
    }
}

Next Go To Unit Of Work
Add Call File in Unit Of Work Which Code is and it inherits from IDisposable and Code is
using BusinessEntities;
using DataModel.GenericRepository;
using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataModel.UnitOfWork
{
    /// <summary>
    /// Unit of Work class responsible for DB transactions
    /// </summary>
    public class UnitOfWork : IDisposable
    {
        #region Private member variables...

        private AdminEntitiesModel _context = null;
        private GenericRepository<TestDepartment> _testEmployeeRepository;

    //  When you add More Table then you write this thing. For Example Designation
 //private GenericRepository<TestDesignation> _testDesignationRepository;

        #endregion

        public UnitOfWork()
        {
            _context = new AdminEntitiesModel();
        }

        #region Public Repository Creation properties...

        /// <summary>
        /// Get/Set Property for city repository.
        /// </summary>
        public GenericRepository<TestDepartment> TestEmployeeRepository
        {
            get
            {
                if (this._testEmployeeRepository == null)
                    this._testEmployeeRepository = new GenericRepository<TestDepartment>(_context);
                return _testEmployeeRepository;
            }
        }
        #endregion

      #region Public Repository Creation properties...

        /// <summary>
        /// Get/Set Property for city repository.
        /// </summary>
        public GenericRepository<TestDesignation> TestDesignationRepository
        {
            get
            {
                if (this._testDesignationRepository == null)
                    this._testDesignationRepository = new GenericRepository<TestDesignation>(_context);
                return _testDesignationRepository;
            }
        }
        #endregion

        #region Public member methods...
        /// <summary>
        /// Save method.
        /// </summary>
        public void Save()
        {
            try
            {
                _context.SaveChanges();
            }
            catch (DbEntityValidationException e)
            {

                var outputLines = new List<string>();
                foreach (var eve in e.EntityValidationErrors)
                {
                    outputLines.Add(string.Format("{0}: Entity of type \"{1}\" in state \"{2}\" has the following validation errors:", DateTime.Now, eve.Entry.Entity.GetType().Name, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        outputLines.Add(string.Format("- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
                    }
                }
                //System.IO.File.AppendAllLines(@"C:\errors.txt", outputLines);

                throw e;
            }

        }

        #endregion

        #region Implementing IDiosposable...

        #region private dispose variable declaration...
        private bool disposed = false;
        #endregion

        /// <summary>
        /// Protected Virtual Dispose method
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    Debug.WriteLine("UnitOfWork is being disposed");
                    _context.Dispose();
                }
            }
            this.disposed = true;
        }

        /// <summary>
        /// Dispose method
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}

Next Go to Web Api
1.       Add Install-Package Microsoft.AspNet.WebApi.HelpPage
2.       for Help Page which is on
4.       For Add this you go to Visual Studio Tools->Nuget PackageManger -> Package Manager Console-> write  Install-Package Microsoft.AspNet.WebApi.HelpPage
    Next Add Install-Package WebApiTestClient   for Designing Test API
Reference URL:

For Unit Resolver You add This thing
 Install-Package Unity -Version 2.1.505.2
And URL is

and in WebApi.config file arr this code
public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
           var container = new UnityContainer();
            container.RegisterType<ITestEmployeeService, TestEmployeeService>(new HierarchicalLifetimeManager());
            //container.RegisterType<IStateService, StateServices>(new HierarchicalLifetimeManager());
            config.DependencyResolver = new UnityResolver(container);
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
         }
        
Next

Next In Global.asax you comment this thing\
//RouteConfig.RegisterRoutes(RouteTable.Routes);




Next On Web Api you add a folder which name is Resolver. And that Resolver you add a class which name is UnityResolver.cs Class.


Next for Write this code UnitResolver class.
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;

namespace WebApi.Resolver
{
    public class UnityResolver : IDependencyResolver
    {
        protected IUnityContainer container;
        public UnityResolver(IUnityContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            try
            {
                return container.Resolve(serviceType);
            }
            catch (ResolutionFailedException)
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return container.ResolveAll(serviceType);
            }
            catch (ResolutionFailedException)
            {
                return new List<object>();
            }
        }

        public IDependencyScope BeginScope()
        {
            var child = container.CreateChildContainer();
            return new UnityResolver(child);
        }

        public void Dispose()
        {
            container.Dispose();
        }
    }
}
Add Namespace which name is using System.Web.Http.Dependencies;
Next for IUnityContainer  You add a dll

One More thing you add this thing on Api.cshtml
@Html.DisplayForModel("TestClientDialogs"

@Html.DisplayForModel("TestClientReferences")



-------------------------------After All ad a controller Which Name Is TestEmployeeController=============================Code Is=============

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using BusinessEntities;
using BusinessServices;
using Newtonsoft.Json.Linq;
using System.Text;
namespace KenAdmin.Controllers
{
    public class TestEmployeeController : ApiController
    {
        private readonly ITestEmployeeService _testEmployeeService;
        public TestEmployeeController()
        {
            _testEmployeeService = new TestEmployeeService();
        }
        public HttpResponseMessage Get()
        {
            try
            {
                var lst = _testEmployeeService.GetAllTestEmployees();
                if (lst != null)
                {
                    return new HttpResponseMessage()
                    {
                        Content = new StringContent(JArray.FromObject(lst).ToString(), Encoding.UTF8, "application/json")
                    };
                    //var testEmployeeEntities = lst as List<TestEmployee> ?? lst.ToList();
                    //if (testEmployeeEntities.Any())
                    //    return Request.CreateResponse(HttpStatusCode.OK, testEmployeeEntities);
                }
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Test Employees not found");
            }
            catch (Exception)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }

        }

        // GET: api/satya/5
        public HttpResponseMessage Get(int id)
        {
            try
            {
                var Temp = _testEmployeeService.GetTestEmployeeById(id);
                //var Temp1 = new StringContent(JArray.FromObject(Temp).ToString(), Encoding.UTF8, "application/json");
                if (Temp != null)
                    return Request.CreateResponse(HttpStatusCode.OK, Temp);
                    //return Request.CreateResponse(HttpStatusCode.OK, new StringContent(JArray.FromObject(Temp).ToString(), Encoding.UTF8, "application/json"));
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Test Employee found for this id");
            }
            catch (Exception)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }
        }


        // POST: api/satya
        //public int Post([FromBody]TestEmployee obj)
        public HttpResponseMessage Post([FromBody]TestEmployee obj)
        
        {
            try
            {

                var res = _testEmployeeService.CreateTestEmployee(obj);
                if (res != null)
                    return Request.CreateResponse(HttpStatusCode.OK, res);
                else
                    return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Data Not Saved");
            }
            catch (Exception)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }
        }


        // PUT: api/satya/5
        public HttpResponseMessage Put(int id, [FromBody]TestEmployee obj)
        {
            try
            {
                TestEmployee res = null;
                if (id >= 0)
                {
                    res = _testEmployeeService.UpdateTestEmployee(id, obj);
                }
                if (res != null)
                    return Request.CreateResponse(HttpStatusCode.OK, res);
                else
                    return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "Data Not Updated");
            }
            catch (Exception)
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }

        }

        // DELETE api/satya/5
        public HttpResponseMessage Delete(int id)
        {
            bool res=false;
            if (id >=0)
                res = _testEmployeeService.DeleteTestEmployee(id);
            if (!res)
                return Request.CreateResponse(HttpStatusCode.OK, res);
            else
                return Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "Cant Be Deleted Reference Exist");
        }
    }

}
==========================================


No comments:

Post a Comment