Translate

Tuesday, July 31, 2018

Organizing ASP.NET MVC Applications

Choosing the right architecture or framework when you embarking doing ASP.NET MVC app is really difficult and tedious task full of traps and tricks. Therefor early planning your MVC application architecture is vital to the success of your project.

I was really over-using union architecture  in my projects for decades already. in my opinion its a robust architecture because of the following:
  • It provides better maintainability of your code since its dividing the project into different layers therefor changing the code is much easier.
  • It provides testability of  your code since you can test each layer code with out affecting other layers.
  • Domain entities and database code are the at the core of the design and are separated from the UI .
  • The internal layers of the design are not depends on the external layers therefor any change change on the external layers will not affect the internal layers.


OA.Data

It is a class library project. It holds POCO classes along with configuration classes. It represents the Domain Entities layer of the onion architecture. These classes are used to create database tables. It’s a core and central part of the application.

using System;
 
namespace OA.Data
{
    public class BaseEntity
    {
        public Int64 Id { getset; }
        public DateTime AddedDate { getset; }
        public DateTime ModifiedDate { getset; }
        public string IPAddress { getset; }
    }

}

OA.Repo

It is a second class library project. It holds generic repository class with its interface implementation. It also holds DbContext class. The Entity Framework Code First data access approach needs to create a data access context class that inherits from the DbContext class. This project represents the Repository layer of the onion architecture.

IRepository interface:
namespace OA.Repo
{
    public interface IRepository<T> where T : BaseEntity
    {
        IEnumerable<T> GetAll();
        T Get(long id);
        void Insert(T entity);
        void Update(T entity);
        void Delete(T entity);
        void Remove(T entity);
        void SaveChanges();
    }

}

namespace OA.Repo
{
    public class Repository<T> : IRepository<T> where T : BaseEntity
    {
        private readonly ApplicationContext context;
        private DbSet<T> entities;
        string errorMessage = string.Empty;
 
        public Repository(ApplicationContext context)
        {
            this.context = context;
            entities = context.Set<T>();
        }
        public IEnumerable<T> GetAll()
        {
            return entities.AsEnumerable();
        }
 
        public T Get(long id)
        {
            return entities.SingleOrDefault(s => s.Id == id);
        }
        public void Insert(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Add(entity);
            context.SaveChanges();
        }
 
        public void Update(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            context.SaveChanges();
        }
 
        public void Delete(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Remove(entity);
            context.SaveChanges();
        }
        public void Remove(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Remove(entity);           
        }
 
        public void SaveChanges()
        {
            context.SaveChanges();
        }
    }
}


OA.Service

It is a third class library project. It holds business logic and interfaces. These interfaces communicate between UI and data access logic. As it communicates via interfaces, it builds applications that are loosely coupled. This project represents the Service layer of the onion architecture.

namespace OA.Service
{
    public  interface IUserService
    {
        IEnumerable<User> GetUsers();
        User GetUser(long id);
        void InsertUser(User user);
        void UpdateUser(User user);
        void DeleteUser(long id);
    }

}

namespace OA.Service
{
    public class UserService:IUserService
    {
        private IRepository<User> userRepository;
        private IRepository<UserProfile> userProfileRepository;
 
        public UserService(IRepository<User> userRepository, IRepository<UserProfile> userProfileRepository)
        {
            this.userRepository = userRepository;
            this.userProfileRepository = userProfileRepository;
        }
 
        public IEnumerable<User> GetUsers()
        {
            return userRepository.GetAll();
        }
 
        public User GetUser(long id)
        {
            return userRepository.Get(id);
        }
 
        public void InsertUser(User user)
        {
            userRepository.Insert(user);
        }
        public void UpdateUser(User user)
        {
            userRepository.Update(user);
        }
 
        public void DeleteUser(long id)
        {           
            UserProfile userProfile = userProfileRepository.Get(id);
            userProfileRepository.Remove(userProfile);
            User user = GetUser(id);
            userRepository.Remove(user);
            userRepository.SaveChanges();
        }
    }

}

OA.Web

It is an ASP.NET Core Web application in this sample but it could be Unit Test or Web API project. It is the most external part of an application by which the end user can interact with the application. It builds loosely coupled applications with in-built dependency injection in ASP.NET Core. It represents the UI layer of the onion architecture.



No comments:

Post a Comment