Odex.AspNetCore.Clarc.Domain 0.1.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Odex.AspNetCore.Clarc.Domain --version 0.1.1
                    
NuGet\Install-Package Odex.AspNetCore.Clarc.Domain -Version 0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Odex.AspNetCore.Clarc.Domain" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Odex.AspNetCore.Clarc.Domain" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="Odex.AspNetCore.Clarc.Domain" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Odex.AspNetCore.Clarc.Domain --version 0.1.1
                    
#r "nuget: Odex.AspNetCore.Clarc.Domain, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Odex.AspNetCore.Clarc.Domain@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Odex.AspNetCore.Clarc.Domain&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Odex.AspNetCore.Clarc.Domain&version=0.1.1
                    
Install as a Cake Tool

🧱 Odex.AspNetCore.Clarc.Domain

NuGet Version NuGet Downloads License: MIT

A robust DDD foundation library for ASP.NET Core applications
Build clean, maintainable domain layers with aggregates, specifications, policies, and CQRS‑ready building blocks.


📦 Overview

Odex.AspNetCore.Clarc.Domain provides a set of base classes, interfaces, and utilities that implement common * Domain‑Driven Design* (DDD) patterns. It is designed to reduce boilerplate code while encouraging consistency, testability, and separation of concerns.

The library focuses on:

  • Aggregates & Entities – Base classes for root aggregates and stateful entities.
  • Domain Events – Lightweight event recording and dispatching support.
  • Specifications – Reusable, composable query logic.
  • Policies – Guard clauses and invariant validation.
  • Repository Abstractions – Async CRUD operations with transactions.
  • Transactional Context – Explicit rollback and commit control.
  • Value Objects – Immutable data containers.

✨ Features

Feature Description
🧩 BaseAggregate Id, CreatedAt, LastModifiedAt, event collection (ListEvents(), AddEvent()).
🔁 StatefulAggregate Adds IsActive / IsSoftDeleted with Activate(), Deactivate(), SoftDelete(), Restore().
📜 Domain Events IDomainEvent – auto‑generated GUID and timestamp.
Policies RequireNotNull, RequireNotNullNorEmpty, RequireTrue/False, etc.
📐 Specifications And, Or, Not combinators – works with EF Core.
🗄️ Repository IAggregateRepository<TEntity, TId> with Add, Update, Delete, FindById, ListAsync.
🔁 Transactions ITransactionContext + ExecuteInTransactionAsync – opt‑in rollback.
⚠️ Domain Exceptions DomainException with ExceptionType enum (Concurrency, NotFound, etc.).
📦 Value Objects BaseValueObject + typed request/response records (PagedRequest, PagedResponse).

🏗️ Core Components

1. Aggregates

public class MyAggregate : StatefulAggregate<Guid>
{
    public string Name { get; private set; }

    public void UpdateName(string newName)
    {
        // Use a policy to guard invariants
        var policy = new BasePolicy<string>();
        policy.RequireNotNullNorEmpty(newName);
        
        Name = newName;
        MarkModified();   // Updates LastModifiedAt
        AddEvent(new NameChangedEvent(Id, newName));
    }
}

2. Policies (Guard Clauses)

var policy = new BasePolicy<MyEntity>();
policy.RequireNotNull(entity);
policy.RequireTrue(entity.IsActive);
policy.RequireNotNullNorEmpty(entity.Code);

3. Specifications

public class ActiveUsersSpec : Specification<User>
{
    public override Expression<Func<User, bool>> ToExpression() 
        => u => u.IsActive;
}

// Usage
var spec = new ActiveUsersSpec().And(new UserNameContainsSpec("john"));
var users = await repository.ListAsync(spec.ToExpression());

4. Repository Usage

public class ProductService : BaseService
{
    private readonly IAggregateRepository<Product, Guid> _productRepo;

    public async Task<Product> CreateProduct(string name)
    {
        var product = new Product(name);
        await _productRepo.AddAsync(product);
        await SaveRepositoryChangesAsync();
        return product;
    }
}

5. Transactions

await ExecuteInRepositoryTransactionAsync(async () =>
{
    await repo1.AddAsync(entityA);
    await repo2.UpdateAsync(entityB);
    return true;   // commits on success
});

🚀 Getting Started

Prerequisites

  • .NET 6.0 or later (support for .NET Standard 2.1)
  • ASP.NET Core (for dependency injection integration)
  • Entity Framework Core (for repository implementations – not included)

Installation

The library is published as a NuGet package (example – replace with actual feed):

dotnet add package Odex.AspNetCore.Clarc.Domain

Or use the Package Manager Console:

Install-Package Odex.AspNetCore.Clarc.Domain

Basic Configuration (DI)

Register your repository and services in the Program.cs or Infrastructure layer:

builder.Services.AddScoped<IMyRepository, MyRepository>();
builder.Services.AddScoped<IMyService, MyService>();

📂 Namespace Map

Namespace Purpose
Odex.AspNetCore.Clarc.Domain.Aggregates BaseAggregate, StatefulAggregate
Odex.AspNetCore.Clarc.Domain.Constants ExceptionType enum
Odex.AspNetCore.Clarc.Domain.Contexts ITransactionContext
Odex.AspNetCore.Clarc.Domain.DTOs BaseData marker
Odex.AspNetCore.Clarc.Domain.Events IAggregateEvent, AggregateEvent
Odex.AspNetCore.Clarc.Domain.Exceptions DomainException (Base exception class), ConcurrencyException, EntityNotFoundException, InvalidEntityStateException, PolicyViolationException
Odex.AspNetCore.Clarc.Domain.Policies IBasePolicy<T>, BasePolicy<T>
Odex.AspNetCore.Clarc.Domain.Repositories IBaseRepository, IAggregateRepository
Odex.AspNetCore.Clarc.Domain.Services IBaseService, BaseService, IAggregateService , AggregateService
Odex.AspNetCore.Clarc.Domain.Specifications Specification (Base specification class), AndSpecification, NotSpecification, OrSpecification, ReplaceParameterVisitor
Odex.AspNetCore.Clarc.Domain.ValueObjects BaseValueObject (Base value object class. Mostly used as marker), Requests.BaseRequests, Requests.PagedRequest, Responses.BaseResponse, Responses.PagedResponse

🧪 Example: Soft‑Delete & Restore

public class Customer : StatefulAggregate<int>
{
    public string Email { get; private set; }

    public void DeleteCustomer()
    {
        SoftDelete();   // sets IsSoftDeleted = true, SoftDeletedAt = now
        AddEvent(new CustomerSoftDeletedEvent(Id));
    }

    public void Reinstate()
    {
        Restore();      // sets IsSoftDeleted = false, RestoredAt = now
        AddEvent(new CustomerRestoredEvent(Id));
    }
}

🤝 Contributing

Contributions are welcome! Please follow the standard GitHub flow:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Make sure to include tests for new functionality.


📄 License

This project is licensed under the MIT License – see the LICENSE file for details.


Built with ❤️ for clean DDD architectures on ASP.NET Core

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Odex.AspNetCore.Clarc.Domain:

Package Downloads
Odex.AspNetCore.Clarc.Infrastructure

Multi-purpose CLARC infrastructure for .NET 9: LINQ query builders, Domain-aligned paging, specification filters, transaction support, and typed infrastructure exceptions. Bring your own ORM or LINQ provider.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 120 5/13/2026
0.1.2 121 4/28/2026
0.1.1 87 4/28/2026
0.1.0 96 4/28/2026