EquinoxProject
Web Application ASP.NET 8 using Clean Architecture, DDD, CQRS, Event Sourcing and a lot of good practices
Top Related Projects
Cross-platform .NET sample microservices and container based application that runs on Linux Windows and macOS. Powered by .NET 7, Docker Containers and Azure Kubernetes Services. Supports Visual Studio, VS for Mac and CLI based environments with Docker CLI, dotnet CLI, VS Code or any other code editor. Moved to https://github.com/dotnet/eShop.
Clean Architecture Solution Template: A starting point for Clean Architecture with ASP.NET Core
Full Modular Monolith application with Domain-Driven Design approach.
ASP.NET Core backend implementation for RealWorld
With Razor Pages
Quick Overview
The EquinoxProject is a full-stack .NET Core application that demonstrates clean architecture principles and best practices for building modern web applications. It showcases Domain-Driven Design (DDD), CQRS (Command Query Responsibility Segregation), and Event Sourcing patterns, providing a comprehensive example of how to structure and implement a scalable, maintainable .NET Core solution.
Pros
- Implements clean architecture and DDD principles, promoting separation of concerns and maintainability
- Demonstrates the use of CQRS and Event Sourcing patterns, which can improve scalability and performance
- Includes a wide range of technologies and practices, such as Entity Framework Core, ASP.NET Core Identity, and MediatR
- Provides a solid foundation for building complex enterprise applications
Cons
- May be overwhelming for beginners due to its comprehensive nature and advanced architectural concepts
- Requires a deep understanding of various design patterns and architectural principles to fully utilize and extend
- Some developers might find the project structure overly complex for smaller applications
- The learning curve can be steep for those not familiar with DDD and CQRS concepts
Code Examples
Here are a few code examples from the EquinoxProject:
- Domain Entity Example:
public class Customer : Entity, IAggregateRoot
{
public Customer(Guid id, string name, string email, DateTime birthDate)
{
Id = id;
Name = name;
Email = email;
BirthDate = birthDate;
}
public string Name { get; private set; }
public string Email { get; private set; }
public DateTime BirthDate { get; private set; }
}
This code defines a Customer entity with properties and a constructor, following DDD principles.
- Command Handler Example:
public class CustomerCommandHandler : CommandHandler,
IRequestHandler<RegisterNewCustomerCommand, bool>,
IRequestHandler<UpdateCustomerCommand, bool>,
IRequestHandler<RemoveCustomerCommand, bool>
{
private readonly ICustomerRepository _customerRepository;
public CustomerCommandHandler(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
public async Task<bool> Handle(RegisterNewCustomerCommand message, CancellationToken cancellationToken)
{
var customer = new Customer(message.Id, message.Name, message.Email, message.BirthDate);
if (!await _customerRepository.GetByEmail(customer.Email) != null)
{
AddError("The customer e-mail has already been taken.");
return false;
}
_customerRepository.Add(customer);
return await Commit(_customerRepository.UnitOfWork);
}
// Other handler methods...
}
This code demonstrates a command handler for customer-related operations, implementing the CQRS pattern.
- Repository Implementation:
public class CustomerRepository : ICustomerRepository
{
protected readonly EquinoxContext Db;
protected readonly DbSet<Customer> DbSet;
public CustomerRepository(EquinoxContext context)
{
Db = context;
DbSet = Db.Set<Customer>();
}
public IUnitOfWork UnitOfWork => Db;
public async Task<Customer> GetById(Guid id)
{
return await DbSet.FindAsync(id);
}
public async Task<Customer> GetByEmail(string email)
{
return await DbSet.AsNoTracking().FirstOrDefaultAsync(c => c.Email == email);
}
public void Add(Customer customer)
{
DbSet.Add(customer);
}
// Other repository methods...
}
This code shows the implementation of a repository for the Customer entity, providing data access methods.
Getting Started
To get started with the EquinoxProject:
- Clone the repository:
git clone https://github.com/EduardoPires/EquinoxProject.git
- Navigate to the project directory:
cd EquinoxProject
- Restore dependencies:
dotnet restore
- Update the database connection string in `ap
Competitor Comparisons
Cross-platform .NET sample microservices and container based application that runs on Linux Windows and macOS. Powered by .NET 7, Docker Containers and Azure Kubernetes Services. Supports Visual Studio, VS for Mac and CLI based environments with Docker CLI, dotnet CLI, VS Code or any other code editor. Moved to https://github.com/dotnet/eShop.
Pros of eShopOnContainers
- More comprehensive, covering a wider range of microservices and cloud-native patterns
- Better suited for large-scale, enterprise-level applications
- Includes containerization and orchestration with Docker and Kubernetes
Cons of eShopOnContainers
- Higher complexity, steeper learning curve for beginners
- May be overkill for smaller projects or simpler applications
- Requires more resources to run and maintain
Code Comparison
EquinoxProject (Domain-Driven Design approach):
public class Customer : Entity, IAggregateRoot
{
public string Name { get; private set; }
public Email Email { get; private set; }
public bool Active { get; private set; }
// Methods and business logic
}
eShopOnContainers (Microservices approach):
[Route("api/v1/[controller]")]
public class CatalogController : ControllerBase
{
private readonly CatalogContext _catalogContext;
private readonly IOptionsSnapshot<CatalogSettings> _settings;
public CatalogController(CatalogContext context, IOptionsSnapshot<CatalogSettings> settings)
{
_catalogContext = context ?? throw new ArgumentNullException(nameof(context));
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
// API endpoints and actions
}
The code snippets highlight the different architectural approaches: EquinoxProject focuses on domain-driven design with rich domain models, while eShopOnContainers emphasizes microservices with API controllers and dependency injection.
Clean Architecture Solution Template: A starting point for Clean Architecture with ASP.NET Core
Pros of CleanArchitecture
- More lightweight and focused on core clean architecture principles
- Includes a comprehensive test suite, demonstrating best practices in testing
- Provides clear separation of concerns with distinct project layers
Cons of CleanArchitecture
- Less feature-rich compared to EquinoxProject
- Doesn't include advanced patterns like CQRS or Event Sourcing
- May require additional setup for more complex applications
Code Comparison
CleanArchitecture:
public class DeleteToDoItemCommand : IRequest
{
public int Id { get; set; }
}
public class DeleteToDoItemCommandHandler : IRequestHandler<DeleteToDoItemCommand>
{
private readonly IRepository<ToDoItem> _repository;
public DeleteToDoItemCommandHandler(IRepository<ToDoItem> repository)
{
_repository = repository;
}
}
EquinoxProject:
public class CustomerCommandHandler : CommandHandler,
IRequestHandler<RegisterNewCustomerCommand, ValidationResult>,
IRequestHandler<UpdateCustomerCommand, ValidationResult>,
IRequestHandler<RemoveCustomerCommand, ValidationResult>
{
private readonly ICustomerRepository _customerRepository;
private readonly IMediatorHandler _mediator;
public CustomerCommandHandler(ICustomerRepository customerRepository,
IUnitOfWork uow,
IMediatorHandler mediator,
INotificationHandler<DomainNotification> notifications) : base(uow, mediator, notifications)
{
_customerRepository = customerRepository;
_mediator = mediator;
}
}
Full Modular Monolith application with Domain-Driven Design approach.
Pros of modular-monolith-with-ddd
- Focuses on modular monolith architecture, which can be easier to maintain and scale compared to microservices
- Provides a more comprehensive example of Domain-Driven Design (DDD) principles
- Includes detailed documentation and architectural decision records (ADRs)
Cons of modular-monolith-with-ddd
- Less emphasis on clean architecture compared to EquinoxProject
- May be more complex for beginners due to its extensive use of DDD concepts
- Lacks some of the additional features present in EquinoxProject, such as identity management
Code Comparison
EquinoxProject (Domain Entity):
public class Customer : Entity
{
public string Name { get; private set; }
public string Email { get; private set; }
public DateTime BirthDate { get; private set; }
}
modular-monolith-with-ddd (Domain Entity):
public class Meeting : Entity, IAggregateRoot
{
public MeetingId Id { get; private set; }
public string Title { get; private set; }
public MeetingTerm Term { get; private set; }
public List<MeetingAttendee> Attendees { get; private set; }
}
Both projects demonstrate the use of domain entities, but modular-monolith-with-ddd shows a more complex implementation with value objects and aggregate roots, aligning closer with DDD principles.
ASP.NET Core backend implementation for RealWorld
Pros of aspnetcore-realworld-example-app
- Implements the RealWorld specification, providing a standardized API and frontend
- Includes comprehensive API documentation using Swagger
- Utilizes AutoMapper for object-to-object mapping, simplifying data transfer
Cons of aspnetcore-realworld-example-app
- Less focus on Domain-Driven Design (DDD) principles compared to EquinoxProject
- Simpler project structure, which may be less suitable for large-scale applications
- Limited use of design patterns and architectural concepts
Code Comparison
EquinoxProject (Domain Entity):
public class Customer : Entity
{
public Customer(Guid id, string name, string email, DateTime birthDate)
{
Id = id;
Name = name;
Email = email;
BirthDate = birthDate;
}
// Properties and methods...
}
aspnetcore-realworld-example-app (Domain Entity):
public class Article
{
public int ArticleId { get; set; }
public string Slug { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Body { get; set; }
// Other properties...
}
The EquinoxProject example demonstrates a more DDD-oriented approach with a constructor and encapsulation, while the aspnetcore-realworld-example-app uses a simpler POCO (Plain Old CLR Object) structure.
With Razor Pages
Pros of ContosoUniversityDotNetCore-Pages
- Simpler architecture, making it easier for beginners to understand and implement
- Focuses on Razor Pages, which can be beneficial for those specifically learning this technology
- Includes more comprehensive documentation and comments within the code
Cons of ContosoUniversityDotNetCore-Pages
- Less scalable for large, complex applications compared to EquinoxProject's DDD approach
- Lacks advanced features like CQRS and Event Sourcing found in EquinoxProject
- Does not demonstrate integration with external services or APIs
Code Comparison
ContosoUniversityDotNetCore-Pages:
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
EquinoxProject:
public class Customer : Entity
{
public Customer(Guid id, string name, string email, DateTime birthDate)
{
Id = id;
Name = name;
Email = email;
BirthDate = birthDate;
}
}
The code comparison shows that ContosoUniversityDotNetCore-Pages uses a simpler model structure, while EquinoxProject implements a more robust domain model with additional features like GUID identifiers and inheritance from a base Entity class.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
What is the Equinox Project?
The Equinox Project is a open-source project written in .NET Core
The goal of this project is implement the most common used technologies and share with the technical community the best way to develop great applications with .NET
Give a Star! :star:
If you liked the project or if Equinox helped you, please give a star ;)
Want to learn everything? :mortar_board:
Check my online courses at desenvolvedor.io
How to use:
- You will need the latest Visual Studio 2022 and the latest .NET Core SDK.
- Please check if you have installed the same runtime version (SDK) described in global.json
- The latest SDK and tools can be downloaded from https://dot.net/core.
Also you can run the Equinox Project in Visual Studio Code (Windows, Linux or MacOS).
To know more about how to setup your enviroment visit the Microsoft .NET Download Guide
Technologies implemented:
- ASP.NET 8.0
- ASP.NET MVC Core
- ASP.NET WebApi Core with JWT Bearer Authentication
- ASP.NET Identity Core
- Entity Framework Core 8.0
- .NET Core Native DI
- AutoMapper
- FluentValidator
- MediatR
- Swagger UI with JWT support
- .NET DevPack
Architecture:
- Full architecture with responsibility separation concerns, SOLID and Clean Code
- Domain Driven Design (Layers and Domain Model Pattern)
- Domain Events
- Domain Notification
- Domain Validations
- CQRS (Imediate Consistency)
- Event Sourcing
- Unit of Work
- Repository
News
v1.9 - 06/31/2024
- Migrated for .NET 8.0
- Full refactoring of Web and Api configuration
- Now all ASP.NET Identity configurations are inside the project, without external dependencies
- All dependencies is up to date
v1.8 - 03/22/2022
- Migrated for .NET 6.0
- All dependencies is up to date
v1.7 - 04/06/2021
- Migrated for .NET 5.0
- All dependencies is up to date
v1.6 - 06/09/2020
- Full Refactoring (consistency, events, validation, identity)
- Added NetDevPack and saving a hundreds of code lines
- All dependencies is up to date
v1.5 - 01/22/2020
- Migrated for .NET Core 3.1.1
- All dependencies is up to date
- Added JWT (Bearer) authentication for WebAPI
- Added JWT support in Swagger
v1.4 - 02/14/2019
- Migrated for .NET Core 2.2.1
- All dependencies is up to date
- Improvements for last version of MediatR (Notifications and Request)
v1.3 - 05/22/2018
- Migrated for .NET Core 2.1.2
- All dependencies is up to date
- Improvements in Automapper Setup
- Improvements for last version of MediatR (Notifications and Request)
- Code improvements in general
v1.2 - 08/15/2017
- Migrated for .NET Core 2.0 and ASP.NET Core 2.0
- Adaptations for the new Identity Authentication Model
v1.1 - 08/09/2017
- Adding WebAPI service exposing the application features
- Adding Swagger UI for better viewing and testing
- Adding MediatR for Memory Bus Messaging
Disclaimer:
- NOT intended to be a definitive solution
- Beware to use in production way
- Maybe you don't need a lot of implementations that is included, try avoid the over engineering
Pull-Requests
Make a contact! Don't submit PRs for extra features, all the new features are planned
Why Equinox?
The Equinox is an astronomical event in which the plane of Earth's equator passes through the center of the Sun, which occurs twice each year, around 20 March and 23 September. Wikipedia
Equinox is also a series of publications (subtitle: "The Review of Scientific Illuminism") in book form that serves as the official organ of the Aâ´Aâ´, a magical order founded by Aleister Crowley :) Wikipedia
We are Online:
See the project running on Azure
About:
The Equinox Project was developed by Eduardo Pires under the MIT license.
Top Related Projects
Cross-platform .NET sample microservices and container based application that runs on Linux Windows and macOS. Powered by .NET 7, Docker Containers and Azure Kubernetes Services. Supports Visual Studio, VS for Mac and CLI based environments with Docker CLI, dotnet CLI, VS Code or any other code editor. Moved to https://github.com/dotnet/eShop.
Clean Architecture Solution Template: A starting point for Clean Architecture with ASP.NET Core
Full Modular Monolith application with Domain-Driven Design approach.
ASP.NET Core backend implementation for RealWorld
With Razor Pages
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot