Introduction

Most projects start as small projects and with time they turn into medium or even large projects. By the time that we realize this is happening, it might be too late and can cost us a lot to change the project architecture.

So why don't we do the whole process in a smarter way and think about this from the beginning?

The separation of concerns is often a neglected topic when dealing with web applications. Everyone who has created even one basic web app knows that by default .NET has a decent template.

That's okay for starters, and for people that are new to these concepts, but if you want to create easily maintainable and extendable applications you should absolutely put in some effort to extend the basic MVC template.

Building the Sample

Building this template requires installed Visual Studio 2015 or later with included .NET Core. Once you have it just build the solution, which will trigger package restore and after a few seconds your solution will be built!

This will trigger bower restore and NuGet package restore.

*If bower restore fails, just save the bower.json and .bowerrc files like this:

Description

What does this architecture give you more than the usual boilerplate templates?

<samp>(Those advantages are applicable for medium to large projects)</samp>

Detailed explanation of the architecture

Data

Services

Tests

Web

Lastly there is a separate project intended to combine all the common classes between all the projects like Global Constants, Global Helper and etc.

Additional Features

C#
  1. public interface IDeletableEntity
  2. {
  3. bool IsDeleted { get; set; }
  4. DateTime? DeletedOn { get; set; }
  5. }
C#
  1. public interface IAuditInfo
  2. {
  3. DateTime CreatedOn { get; set; }
  4. DateTime? ModifiedOn { get; set; }
  5. }
C#
  1. public abstract class BaseModel<TKey> : IAuditInfo
  2. {
  3. [Key] public TKey Id { get; set; }
  4. public DateTime CreatedOn { get; set; }
  5. public DateTime? ModifiedOn { get; set; }
  6. }
C#
  1. public abstract class BaseDeletableModel<TKey> : BaseModel<TKey>, DeletableEntity
  2. {
  3. public bool IsDeleted { get; set; }
  4. public DateTime? DeletedOn { get; set; }
  5. }
Now we can use these base classes and prevent adding their properties in each of our classes separately like this.
Generic Repositiry Pattern

Creating some kind of abstraction over the database is almost mandatory when talking about a real project.
C#
  1. public interface IRepository < TEntity >: IDisposable where TEntity: class
  2. {
  3. IQueryable < TEntity > All();
  4. IQueryable < TEntity > AllAsNoTracking();
  5. Task < TEntity > GetByIdAsync(params object[] id);
  6. void Add(TEntity entity);
  7. void Update(TEntity entity);
  8. void Delete(TEntity entity);
  9. Task < int > SaveChangesAsync();
  10. }
Our repository shoud contain all operations needed for work with our database like:

or so called CRUD operations. In the provided solution we have two implementaions of the interface EfRepository.csand EfDeletableEntityRepository.cs

Source Code Files