Home

Clean Architecture example in C#

Core (Domain) Layer

Entities/Product.cs

namespace MyApp.Core.Entities
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }

        public decimal GetDiscountedPrice(decimal discountedPercentage)
        {
            return Price - (Price * discountedPercentage / 100);
        }
    }
}

Interfaces/IProductRepository.cs

namespace MyApp.Core.Interfaces
{
    public interface IProductRepository
    {
        Product GetProductById(int id);
        void AddProduct(Product product);
        void UpdateProduct(Product product);
        IEnumerable<Product> GetAllProducts();
    }
}

Application Layer

UseCases/ProductService.cs

using MyApp.Core.Entities;
using MyApp.Core.Interfaces;
using System.Collections.Generic;

namespace MyApp.Application.UseCases
{
    public class ProductService
    {
        private readonly IProductRepository _productRepository;

        public ProductService(IProductRepository productRepository)
        {
            _productRepository = productRepository;    
        }

        public Product GetProduct(int id)
        {
            return _productRepository.GetProductById(id);
        }

        public void CreateProduct(Product product)
        {
            _productRepository.AddProduct(product);
        }

        public void UpdateProduct(Product product)
        {
            _productRepository.UpdateProduct(product);
        }

        public void DeleteProduct(int id)
        {
            _productRepository.DeleteProduct(id);
        }

        public IEnumerable<Product> GetAllProducts()
        {
            return _productRepository.GetAllProducts();
        }
    }
}

Infrastructure Layer

Data/ApplicationDbContext.cs:

using Microsoft.EntityFrameworkCore;
using MyApp.Core.Entities;

namespace MyApp.Infrastructure.Data
{
    public class ApplicationDbContext : DbContext
    {
        public DbSet<Product> Products { get; set; }

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }
    }
}

Repositories/ProductRepository.cs

using MyApp.Core.Entities;
using MyApp.Core.Interfaces;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;

namespace MyApp.Infrastructure.Repositories
{
    public class ProductRepository : IProductRepository
    {
        private readonly ApplicationDbContext _context;

        public ProductRepository(ApplicationDbContext context)
        {
            _context = context;
        }

        public Product GetProductById(int id)
        {
            return _context.Products.Find(id);
        }

        public void AddProduct(Product product)
        {
            _context.Products.Add(product);
            _context.SaveChanges();
        }

        public void UpdateProduct(Product product)
        {
            _context.Products.Update(product);
            _context.SaveChanges();
        }

        public void DeleteProduct(int id)
        {
            var product = _context.Products.Find(id);
            if (product != null)
            {
                _context.Products.Remove(product);
                _context.SaveChanges();
            }
        }
        
        public IEnumerable<Product> GetAllProducts()
        {
            return _context.Products.ToList();
        }
    }
}

Presentation Layer

Controller/ProductController.cs:

using Microsoft.AspNetCore.Mvc;
using MyApp.Application.UseCases;
using MyApp.Core.Entities;

namespace MyApp.Presentation.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductController : ControllerBase
    {
        private readonly ProductService _productService;

        public ProductController(ProductService productService){
            _productService = productService;
        }

        [HttpGet("{id}")]
        public IActionResult GetProduct(int id)
        {
            var product = _productService.GetProduct(id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok();
        }

        [HttpPost]
        public IActionResult CreateProduct([FromBody]Product product)
        {
            _productService.CreateProduct(product);
            return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
        }
    }
}

Date:

Screen Dimensions