Phymnary.SugarPot.AspNetCore.Domain 1.2.2

dotnet add package Phymnary.SugarPot.AspNetCore.Domain --version 1.2.2
                    
NuGet\Install-Package Phymnary.SugarPot.AspNetCore.Domain -Version 1.2.2
                    
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="Phymnary.SugarPot.AspNetCore.Domain" Version="1.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Phymnary.SugarPot.AspNetCore.Domain" Version="1.2.2" />
                    
Directory.Packages.props
<PackageReference Include="Phymnary.SugarPot.AspNetCore.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 Phymnary.SugarPot.AspNetCore.Domain --version 1.2.2
                    
#r "nuget: Phymnary.SugarPot.AspNetCore.Domain, 1.2.2"
                    
#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 Phymnary.SugarPot.AspNetCore.Domain@1.2.2
                    
#: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=Phymnary.SugarPot.AspNetCore.Domain&version=1.2.2
                    
Install as a Cake Addin
#tool nuget:?package=Phymnary.SugarPot.AspNetCore.Domain&version=1.2.2
                    
Install as a Cake Tool

Phymnary.SugarPot.AspNetCore.Domain

Shared domain contracts and primitives for SugarPot ASP.NET Core stacks.

This project contains contracts only (interfaces, attributes, DTO-like primitives, and exception types). It does not provide persistence, transport, or host-specific runtime implementations.

Package scope

The root namespace is:

Phymnary.SugarPot.AspNetCore

Main groups:

  • Domain/runtime context contracts
  • Entity and validation primitives
  • Repository and advanced query contracts
  • Auditing contracts and metadata helpers
  • Multi-tenancy and security context contracts
  • Domain/business exception abstractions

Contracts by area

Runtime and scope contracts

  • IAbortedToken
    • CancellationToken Get(CancellationToken cancellationToken)
  • IRunAt
    • DateTimeOffset Value { get; }
  • IScopeBuilder
    • AsyncServiceScope Initialize(ScopeContext context)
  • ScopeContext
    • CurrentUserId, CurrentTenantId, RequestAborted
  • IDbFunctionProvider
    • BeginTransactionAsync(...)
    • UseResilientStrategyAsync(...)
    • UseResilientStrategyWithTransactionAsync(...)

Entity contracts

  • IEntity
    • exposes EntityDomainStatus DomainStatus
  • Entity<TKey>
    • base class with [Key] TKey Id { get; protected init; }
  • EntityDomainStatus
    • IsAdded, IsSoftDeleted, OnAttached(), SoftDelete()
  • ISoftDelete
    • DeletedById, DeletedAt, and default Delete() implementation that flags domain status

Validation contracts

  • IEntityValidator<TEntity>
    • ValueTask<EntityValidationResult> ValidateAsync(...)
  • EntityValidationResult
    • IsValid, Errors, plus static Valid
  • EntityValidationFailureDetail
    • Property, Message, optional Code

Repository contracts

  • IRepository<TEntity>
    • write methods: InsertAsync, UpsertAsync, UpdateAsync, Delete
    • read methods: FindAsync, QueryAsync, AnyAsync, CountAsync
    • advanced query entry point: AdvanceQuery(...)
  • IRepository<TEntity, TKey>
    • adds GetAsync(TKey id, ...)
  • IQueryTransaction
    • transaction lifecycle and savepoint-related API

Advanced query contracts

  • IAdvanceOrderBuilding<T>
  • IAdvancePageBuilding<T>
  • IAdvanceSelectableBuilding<T>
  • IAdvanceQueryBuilder<T>
  • PaginateResult<TEntity>

The flow is designed as a staged builder:

  1. Order (OrderBy / OrderByDescending)
  2. Page (Pick)
  3. Optional projection (Select)
  4. Execute (PaginateAsync or Build)

Auditing contracts

  • IAuditable
    • audit identity (GetAuditKey) and created/updated fields
  • IPropertyChangeAudit
    • immutable shape for property change records
  • AuditingAttribute
    • class-level include list of auditable properties
  • DisabledAuditingAttribute
    • class/property-level opt-out
  • EntityPropertyAuditingMetadata
    • computes if a property can be audited via CanAudit(...)
  • AuditingEntityMapper<TConcrete, TImplement>
    • mapping hook via Func<TConcrete, TImplement>
  • TrackBy
    • Domain or Database

Multi-tenancy and security contracts

  • IMultiTenant
    • Guid TenantId { get; set; }
  • ICurrentTenant
    • Guid? Id { get; }
  • ICurrentUser
    • Guid? Id { get; }

Exception contracts and types

  • IBusinessException
    • HttpStatusCode StatusCode, optional ErrorCode
  • IDomainException : IBusinessException

Provided domain exception classes:

  • DomainNotImplementedException (422 UnprocessableContent)
  • EntityNotFoundException (404 NotFound)
  • EntityValidationException (400 BadRequest, includes Failures)
  • EntityPersistenceException (409 Conflict)
  • TenantMissingInContextException (403 Forbidden)

Error code defaults are configurable globally through DomainErrorCodeRegistry.

Extension helpers

  • EntityExtensions.Attach(...)
    • Adds an entity to an ICollection<T> and marks DomainStatus.IsAdded
  • ServiceProviderExtensions.InheritAsyncServiceScope(...)
    • Builds ScopeContext from current user/tenant/aborted token services and initializes a new async scope

Note: ServiceProviderExtensions is declared in namespace Phymnary.SugarPot.AspNetCore.Api.Extensions.

Installation

NuGet:

dotnet add package Phymnary.SugarPot.AspNetCore.Domain

Usage examples

Define an entity

using Phymnary.SugarPot.AspNetCore.Entities;

public sealed class User : Entity<Guid>, ISoftDelete
{
    public User(Guid id) : base(id) { }

    public string Name { get; set; } = string.Empty;

    public Guid? DeletedById { get; set; }

    public DateTimeOffset? DeletedAt { get; set; }
}

Attach child entity and mark as added

using Phymnary.SugarPot.AspNetCore.Entities;
using Phymnary.SugarPot.AspNetCore.Extensions;

var addresses = new List<Address>();
var address = addresses.Attach(new Address(Guid.NewGuid()));

// address.DomainStatus.IsAdded == true

Implement entity validation

using Phymnary.SugarPot.AspNetCore.Entities;

public sealed class UserValidator : IEntityValidator<User>
{
    public ValueTask<EntityValidationResult> ValidateAsync(
        User entity,
        CancellationToken cancellationToken = default)
    {
        if (string.IsNullOrWhiteSpace(entity.Name))
        {
            return ValueTask.FromResult(new EntityValidationResult
            {
                IsValid = false,
                Errors =
                [
                    new EntityValidationFailureDetail
                    {
                        Property = nameof(User.Name),
                        Message = "Name is required",
                        Code = "USR_NAME_REQUIRED"
                    }
                ]
            });
        }

        return ValueTask.FromResult(EntityValidationResult.Valid);
    }
}

Throw standardized domain exceptions

using Phymnary.SugarPot.AspNetCore.Exceptions;

throw new EntityNotFoundException("User not found")
    .WithErrorCode("USR_NOT_FOUND");

Design intent

  • Keep this package implementation-agnostic.
  • Place EF Core, database, messaging, and host-specific logic in other packages.
  • Use these contracts to keep domain and application layers stable and testable.

Build metadata

Version is provided via $(AspPackedVersion) from the parent build configuration.

License

See the repository root for license details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  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 is compatible.  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.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Phymnary.SugarPot.AspNetCore.Domain:

Package Downloads
Phymnary.SugarPot.AspNetCore.Application

Package Description

Phymnary.SugarPot.AspNetCore.EntityFrameworkCore

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 133 9/18/2026
1.2.1 197 7/27/2026
1.2.0 274 6/15/2026
1.1.0 191 6/7/2026
1.0.0 198 6/5/2026