Skip to main content
ESP Santa Fe de Antioquia is built using ASP.NET Core MVC following a layered architecture pattern with clear separation of concerns.

Architecture Layers

Project Structure

The solution is organized into multiple projects for better separation:
The main web application project containing:
  • Controllers: MVC controllers handling HTTP requests
  • Views: Razor views for UI rendering
  • Models: View models for data transfer to views
  • Areas: Identity area for authentication pages
  • Config: Configuration classes (AutoMapper, etc.)
  • Startup.cs: Application configuration and DI setup

Core Design Patterns

MVC Pattern

The application follows the Model-View-Controller pattern:
// Controller: prjESPSantaFeAnt/Controllers/ProductsController.cs:11
public class ProductsController : Controller
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    // GET: Products
    public async Task<IActionResult> Index()
    {
        var _product = from a in await _productService.GetAll()
                       select new ModelViewProduct
                       {
                           ProductId = a.ProductId,
                           Icono = a.Icono,
                           Name = a.Name,
                           UrlProduct = a.UrlProduct
                       };

        return View(_product);
    }
}
Controllers are thin, delegating business logic to services. They only handle HTTP concerns like request validation, routing, and view selection.

Repository Pattern

While not using formal repositories, services act as a repository layer:
// Service interface
public interface IProductService
{
    Task<IEnumerable<Product>> GetAll();
    Task<ProductDto> Details(int? id);
    Task<ProductDto> Create(ProductCreateDto model);
    Task DeleteConfirmed(int id);
    bool ProductExists(int id);
}

Dependency Injection

All services and dependencies are registered in Startup.cs:26:
public void ConfigureServices(IServiceCollection services)
{
    // Database Context
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    // Identity
    services.AddIdentity<IdentityUser, IdentityRole>(
        options => options.SignIn.RequireConfirmedAccount = true)
       .AddEntityFrameworkStores<ApplicationDbContext>()
       .AddDefaultTokenProviders();

    // AutoMapper
    services.AddAutoMapper(typeof(Startup));

    // Business Services
    services.AddTransient<ICategoryService, CategoryService>();
    services.AddTransient<IProductService, ProductService>();
    services.AddTransient<IEmployeeService, EmployeeService>();
    // ... more services

    // Common Services
    services.AddTransient<IUploadedFileIIS, UploadedFileIIS>();
    services.AddTransient<IEmailSendGrid, EmailSendGrid>();
}

Request Pipeline

The middleware pipeline is configured in Startup.cs:96:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsProduction())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapRazorPages();
    });
}

Key Architectural Benefits

Separation of Concerns

  • Presentation logic isolated in controllers and views
  • Business logic encapsulated in services
  • Data access centralized in DbContext and configurations

Testability

  • Services use interfaces for easy mocking
  • Constructor injection enables unit testing
  • Business logic independent of web concerns

Maintainability

  • Clear project boundaries
  • Single Responsibility Principle
  • Easy to locate and modify functionality

Scalability

  • Stateless services
  • Transient lifetime for most services
  • Database connection pooling via EF Core

Technology Stack

LayerTechnology
FrameworkASP.NET Core 3.1
ORMEntity Framework Core
DatabaseSQL Server
AuthenticationASP.NET Core Identity
MappingAutoMapper
UIRazor Views, MVC
EmailSendGrid

Configuration Management

Configuration is managed through:
  • appsettings.json for application settings
  • Connection strings in configuration
  • Dependency injection for accessing IConfiguration
// Startup.cs:18
public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

Next Steps

Database Schema

Explore the database structure and entity relationships

Services Layer

Deep dive into business logic and service patterns

Authentication

Learn about security and authentication implementation

Build docs developers (and LLMs) love