Giter Site home page Giter Site logo

nilavpatel / dotnet-onion-architecture Goto Github PK

View Code? Open in Web Editor NEW
75.0 2.0 14.0 265 KB

.Net onion/clean architecture sample

License: MIT License

C# 100.00%
architecture csharp asp-net-core onion-architecture architectural-patterns webapi clean clean-architecture moq xunit-tests

dotnet-onion-architecture's Introduction

Onion Architecture / Clean Architecture

  • Onion architecture can solve problem of separation of concern and tightly coupled components from N-layered architecture.
  • All layers are depended on inner layer.
  • The core of the application is the domain layer.
  • Provide more testability than N-layered architecture.

Layers

Domain Layer:

This layer does not depend on any other layer. This layer contains entities, enums, specifications etc.
Add repository and unit of work contracts in this layer.

Application Layer:

This layer contains business logic, services, service interfaces, request and response models.
Third party service interfaces are also defined in this layer.
This layer depends on domain layer.

Infrastructure Layer:

This layer contains database related logic (Repositories and DbContext), and third party library implementation (like logger and email service).
This implementation is based on domain and application layer.

Presentation Layer:

This layer contains Webapi or UI.

Domain model

Domain model are of 2 types

  1. Domain entity (data only)

    • This model contains only fields
    • This is an anti pattern used widely. Read blog from Martin Fowler (here)
  2. Domain model (data + behaviour)

    • This model has fields and behaviours. Fields can be modify only within behaviours.
    • Follow Aggregate pattern with Aggregate root, Value object, Entity, Bounded context, Ubiqutous language

Validations in Domain driven design:

There are 2 types of validations in DDD:

  1. Model Field validations

    • Properties having valid length
    • required field validations
    • regex

    Model validations can be validated in Application layer or Domain layer.

  2. Business validations

    • Balance should be more than Withdraw amount
    • User should be active
    • User name should not be exist

    Business validations can be validated in Applciation layer or Domain layer.

    Business validations have two types:

    1. Validations in same domain model
      • Balance should be more than Withdraw amount
      • User should be active
    2. Validations against other domain models
      • User name should not be already exist

For Aggregate pattern add both types of validations inside domain layer.

Problem occurs when validating domain model against other domain models.

  • In this case use Func<> methods to pass validations to domain model from Application layer.
    And run this Func<> from domain models.
public WithdrawMoney(double amount, Func<string, bool> isBankAccountActive){
    if(!isBankAccountActive(BankAccountNumber)){
        throw new DomainValidationException("Bank account is not in active state");
    }
}
  • Otherwise pass domain model of other type as parameter and then validate.
public WithdrawMoney(double amount, BankAccount bankAccount){
    if(bankAccount.Status != Active){
        throw new DomainValidationException("Bank account is not in active state");
    }
}

For more details read

Technologies Used:

  • .Net 8
  • Rest API
  • Entity Framework
  • NLog
  • Swagger
  • Xunit
  • Moq
  • Generic Repository Pattern
  • Specification pattern

dotnet-onion-architecture's People

Contributors

nilavpatel avatar zandiarash avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

dotnet-onion-architecture's Issues

Mistake in readme file

Infrastructure Layer:
This layer contains database related logic (Repositories and DbContext), and third party library implementation (like a logger and email service).
This implementation is based on domain and infrastructure layer.

Its not based on infrastructure layer because it is infrastructure layer.

This solution need more separation of concerns

Dear NilavPatel,
Thank you for this sample, But i think this solution need more separation of concerns, I will explain where and why.

  1. Data and services both are in one project, This make it hard to refactor or changing technology for specific part, For example if i want to change my DBProvider from EFCore to MondoDb, I need to create new project for infrastructure which contain EmailService and LoggerService, These kind of code should be separated.

  2. Application layer should only orchestrate whole application, It should contain any interface of any service, All interface and contracts should be in domain layer, But i suggest create domain layer as folder because domain layer should have more than one project.
    Example :
    MyApp.Domain.Data
    MyApp.Domain.Service
    MyApp.Domain.Shared
    MyApp.Domain.Contract

  3. Same thing should happen to infrastructure layer, It need to be a folder which contains :
    MyApp.Infrastructure.DataEFCore
    MyApp.Infrastructure.Service
    (if you want to separate even better : MyApp.Infrastructure.LoggerService, MyApp.Infrastructure.EmailService)

If you do this, You be abble change your DBProvider easily by adding another project like MyApp.Infrastructure.DataMongoDb without implement your EmailService and LoggerService, You only need to call another dependency resolver in your WebApi project.

About MyApp.DbMigrations i have to say i didn't get why this project exists, This logic and code should be in MyApp.Infrastructure.DataEFCore project.

The whole solution could be something like this :
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.