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 {
get
;
set
; }
public
DateTime AddedDate {
get
;
set
; }
public
DateTime ModifiedDate {
get
;
set
; }
public
string
IPAddress {
get
;
set
; }
}
}
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:
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.