Skip to content
CAI
Software that uses CAICheck a score

xhafan/coreddd

51.4

Adequate · 21 September 2026

5.6k

lines of production code

C#

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

CoreDdd is a .NET library suite that provides a Domain-Driven Design (DDD) and CQRS infrastructure, centered around a Unit of Work pattern for database transactions. It offers NHibernate integration for persistence, supports asynchronous operations, and integrates with multiple IoC containers like Castle Windsor and Ninject. The system also includes utilities for domain events, ambient storage, and testing helpers to facilitate building robust, transactional applications.

Features

Add ASP.NET Core middlewares to skip default database transactions for specific requests

The CoreDdd.AspNetCore package now includes new middleware classes (BaseTransactionScopeUnitOfWorkMiddleware, BaseUnitOfWorkMiddleware, and their concrete implementations) that allow developers to configure the framework to skip creating the default request database transaction for specific HTTP request paths. This is achieved by passing a list of regular expressions representing GET or HEAD request paths that should bypass transaction creation, which can improve performance for read-only or non-transactional endpoints.

src · high confidence

Add ServiceProvider-based IoC container and DI registration extensions

Users can now resolve services using the standard Microsoft.Extensions.DependencyInjection IServiceProvider via a new CoreIoC.ServiceProvider project that wraps the ServiceProvider as an IContainer implementation. Additionally, CoreDdd and CoreDdd.Nhibernate projects provide static extension methods (AddCoreDdd, AddCoreDddNhibernate) to register command/query handlers, executors, and NHibernate-related services into the service provider, enabling consistent dependency injection across the application.

src/CoreDdd.Nhibernate.Register.ServiceProvider, src/CoreDdd.Register.ServiceProvider, src/CoreIoC.ServiceProvider · medium confidence

Add async support to Rebus unit of work implementations

The \RebusUnitOfWork\ and \RebusTransactionScopeUnitOfWork\ classes in the \CoreDdd.Rebus.UnitOfWork\ library now include asynchronous counterparts (\CreateAsync\, \CommitAsync\, \RollbackAsync\, and \CleanupAsync\) alongside their synchronous versions. This allows developers to handle Rebus messages using \async/await\ patterns, improving scalability for I/O-bound operations within the unit of work lifecycle.

src/CoreDdd.Rebus.UnitOfWork · high confidence

Added ASP.NET HTTP modules for transactional and non-transactional unit of work management

Introduced two new HTTP modules in the CoreDdd.AspNet project: TransactionScopeUnitOfWorkHttpModule and UnitOfWorkHttpModule. The TransactionScopeUnitOfWorkHttpModule wraps each web request in a System.Transactions.TransactionScope, enabling distributed transaction support for ASP.NET applications. The UnitOfWorkHttpModule provides a simpler, non-transactional unit of work lifecycle. Both modules handle request lifecycle events to begin and commit/rollback unit of work operations, with the transactional module specifically requiring .NET 4.5.1 or higher due to the use of TransactionScopeAsyncFlowOption.Enabled.

src/CoreDdd.AspNet · medium confidence

Added collection and type extension methods

New extension methods are now available for working with collections and types. The \CollectionExtensions\ class provides utility methods including \Each\ (with and without index), \IsEmpty\, and \Second\ for \IEnumerable\<T\>\ types. Additionally, \TypeExtensions\ introduces \IsSubclassOfRawGeneric\ to check if a type is a subclass of a given generic type, with implementation details that adapt to different .NET framework versions.

src/CoreUtils/Extensions · high confidence

Added shared test infrastructure for non-integer entity IDs and transaction scopes

The shared integration test project now includes support for entities with non-integer identifiers (long, string, and composite keys) and a volatile resource manager for transaction scope testing. Specifically, the \IntegrationTestsShared\ project now contains \EntitiesWithNonIntegerId\ (including \CompositeId\, \EntityWithCompositeId\, \EntityWithLongId\, and \EntityWithStringId\) and a \VolatileResourceManager\ in \TransactionScopes\ to facilitate testing with \TransactionScope\.

src/IntegrationTestsShared/EntitiesWithNonIntegerId, src/IntegrationTestsShared/TransactionScopes · high confidence

Added test helpers for domain events and HTTP context

The CoreDdd.TestHelpers project now includes FakeDomainEventHandler and FakeDomainEventHandlerFactory to simplify unit testing of domain events, alongside a FakeHttpContextHelper to facilitate unit testing of code that relies on HttpContext.Current.

src/CoreDdd.TestHelpers · medium confidence

Adds NHibernate unit of work extension methods for testing

The \CoreDdd.Nhibernate.TestHelpers\ library now provides a new \NhibernateUnitOfWorkExtensions\ class containing extension methods for \NhibernateUnitOfWork\. These include \Save\, \Get\, \LoadById\, \Load\, and \Delete\ methods that wrap the corresponding \NhibernateRepository\ operations. Notably, \LoadById\ is designed to throw an exception if the requested entity is not found, while \Get\ returns null in that case. This change replaces the previous \PersistenceTestHelper\ file, consolidating test utilities into a single extension class.

src/CoreDdd.Nhibernate.TestHelpers · high confidence

Initial release of CoreDdd libraries and documentation

The repository now includes the MIT license and a README that introduces the CoreDdd library suite for domain-driven design and CQRS. The README lists the available NuGet packages (CoreDdd, CoreDdd.Nhibernate, CoreDdd.AspNetCore, etc.) and links to documentation, samples, and real-world usage examples. The previous solution file (EmailMaker.sln) has been removed, indicating a restructuring of the project layout.

(repo-wide) · high confidence

Introduce AmbientStorage for context-aware data storage

Added a new AmbientStorage class that provides a unified way to store and retrieve data based on the current execution context. For ASP.NET environments, it uses HttpContext.Current.Items; for older .NET Framework versions, it uses CallContext.LogicalGetData/SetData; and for modern .NET/.NET Standard, it utilizes AsyncLocal storage. This abstraction simplifies domain event handling by replacing the previous IStorage/IStorageFactory IoC container services with a more developer-friendly approach.

src/CoreUtils/AmbientStorages · medium confidence

Introduce Castle Windsor installer for NHibernate repository services

Users can now register CoreDdd NHibernate services into the Castle Windsor IoC container via the new \CoreDddNhibernateInstaller\. This installer registers \IRepository\<\>\ and \IRepository\<,\>\ implementations, as well as the \IUnitOfWorkFactory\ as a factory, allowing the framework to integrate with Castle Windsor for dependency injection. The installer also ensures the \TypedFactoryFacility\ is added to the container if not already present.

src/CoreDdd.Nhibernate.Register.Castle · high confidence

Introduce CoreIoC abstraction with support for Castle Windsor and Ninject

Developers can now use a unified \CoreIoC\ interface to resolve services from either Castle Windsor or Ninject IoC containers. The \CoreIoC\ namespace provides a static \IoC\ service locator that wraps the chosen container, supporting resolution by type, by name, and collection resolution, as well as explicit release of resolved instances. The \IContainer\ interface and concrete implementations (\CastleContainer\, \NinjectContainer\) enable swapping or selecting an IoC framework at initialization.

src/CoreIoC · high confidence

Introduce NhibernateUnitOfWorkRunner for automatic transaction management

Added NhibernateUnitOfWorkRunner, a new static helper class that executes operations within a unit of work with automatic transaction handling: it commits on success, rolls back on failure, and disposes the session safely. This provides a convenient way to manage NHibernate transactions without manual commit/rollback logic in application code.

src/CoreDdd.Nhibernate/UnitOfWorks · high confidence

Introduces configurable NHibernate automapping and naming strategy

The NHibernate configuration layer now exposes \BaseNhibernateConfigurator\ and \AutomappingConfiguration\ classes that allow developers to control how domain entities, DTOs, and NHibernate components are mapped to the database. Users can now explicitly enable or disable DTO mapping, define discriminated types for inheritance mapping, and override the default conventions to customize behavior. Additionally, a new \DoubleQuoteIdentifiersNamingStrategy\ is introduced to wrap table and column names in double quotes, preventing SQL errors caused by reserved keywords.

src/CoreDdd.Nhibernate/Configurations · high confidence

New NHibernate conventions for nullability, DTO handling, and schema mapping

The library introduces several new conventions in the NHibernate mapping layer. Column nullability is now automatically inferred from nullable reference types. DTOs are loaded as read-only to prevent unwanted database updates, and lazy loading is disabled for them. Additional conventions define foreign key naming, primary key generation via HiLo, string column lengths, and datetime precision, while also supporting IDictionary collections as maps.

src/CoreDdd.Nhibernate/Conventions · high confidence

New database schema generation and creation utilities

Added DatabaseSchemaGenerator to produce SQL scripts from NHibernate mappings, and DatabaseSchemaCreator to execute schema creation against a live database, including a workaround for SQL Server schema-existence issues.

src/CoreDdd.Nhibernate/DatabaseSchemaGenerators · medium confidence

Removals

Removed obsolete domain and assembly metadata files

The abstract class TemplatePartContainer and the AssemblyInfo metadata file have been removed from the EmailMaker.Domain project. This cleanup eliminates unused or legacy components from the domain layer, simplifying the codebase by removing the TemplatePartContainer class and associated assembly attributes.

EmailMaker.Domain · high confidence

Behavioural changes

Async commit/rollback and isolation level support added to Unit of Work

The IUnitOfWork interface now supports asynchronous commit and rollback operations, allowing for non-blocking transaction management in modern .NET environments. Additionally, the interface has been updated to accept an IsolationLevel parameter when beginning a transaction, giving users more control over database concurrency behavior. A new IUnitOfWorkFactory interface has also been introduced to facilitate unit of work creation, typically via an IoC container.

src/CoreDdd/UnitOfWorks · medium confidence

Async method support with version constraints

Added async support for query handlers, with a runtime check that enforces .NET 4.6.1+ for NHibernate queries. If an async method is used on an older .NET/NHibernate version, the system throws a clear error message directing users to use the synchronous alternative instead.

src/CoreDdd.Nhibernate · medium confidence

Async query execution and single-result support for NHibernate handlers

The NHibernate query handlers now support asynchronous execution and single-result queries. New methods (ExecuteSingle, ExecuteSingleAsync) allow retrieving a single result from a query, while ExecuteAsync and ExecuteSingleAsync provide async execution for .NET 4.5+ (ADO.NET) and .NET 4.6.1+ (NHibernate) targets. This change enables more efficient handling of single-value queries and improves performance through async/await patterns.

src/CoreDdd.Nhibernate/Queries · high confidence

Consolidate Castle Windsor installer into a single registration point

The Castle Windsor integration for CoreDdd has been refactored to use a single, unified installer (CoreDddInstaller) that registers command and query executors and their respective factories. This change consolidates previous separate installers into one per assembly, simplifying the IoC configuration for Castle Windsor users.

src/CoreDdd.Register.Castle · medium confidence

Consolidated shared integration test infrastructure

Shared integration test code has been moved into the new IntegrationTestsShared project, consolidating base classes and configuration for NHibernate-based tests. This includes the BasePersistenceTest and BaseRunOncePerTestRun base classes, along with the TestNhibernateConfigurator and TestNhibernateInstaller, providing a unified foundation for integration tests across different frameworks.

src/IntegrationTestsShared · high confidence

Consolidated shared test entities into the IntegrationTestsShared project

The shared integration test entities have been moved from the EmailMaker.Domain project into the new IntegrationTestsShared/TestEntities directory. This includes the base Entity and DomainEvent classes, as well as specific test models such as ParentEntity, ChildEntity, and various nullable reference type entities, providing a centralized location for test fixtures used across the solution.

src/IntegrationTestsShared/TestEntities · high confidence

Enhanced Guard.Hope with exception data and nullable reference type support

The Guard.Hope method now supports adding arbitrary data to the thrown exception, allowing developers to attach additional context to validation failures. Additionally, the library now includes embedded JetBrains annotations to support nullable reference types, which eliminates false-positive null-reference warnings in modern .NET environments without requiring external packages.

src/CoreUtils · medium confidence

Enhanced NHibernate repository with locking, async support, and long ID defaults

The NHibernate repository implementation has been expanded to support entity locking via new \Get\ and \Load\ methods that accept a \LockMode\ parameter, allowing for optimistic or pessimistic locking strategies. Additionally, asynchronous variants (\GetAsync\, \LoadAsync\, \LoadByIdAsync\) have been added for modern .NET runtimes, and the default entity identifier type has been changed from \int\ to \long\ (with a specialized \NhibernateRepositoryInt\ provided for \int\-based entities).

src/CoreDdd.Nhibernate/Repositories · medium confidence

Entity base class now defaults to long IDs, with an int variant added

The default entity base class in CoreDdd.Domain now uses a long identifier instead of int, which is a breaking change for existing code relying on int IDs. To support int-based identifiers, a new EntityInt base class has been introduced. Users creating new entities will now inherit from Entity (long) by default, while those needing int IDs should inherit from EntityInt.

CoreDdd · high confidence

Introduced generic Entity base class and IAggregateRoot interface

Added the generic \Entity\<TId\>\ base class for domain entities with a custom identifier type, featuring an overridden \Equals\ method that supports comparison with parent entity proxies via \GetUnproxiedType\. The class also implements \==\ and \!=\ operators for equality checks. Additionally, the \IAggregateRoot\ marker interface was added to identify aggregate root entities.

src/CoreDdd/Domain · high confidence

Introduces generic query interfaces and async execution support

The query execution architecture has been refactored to support both single and collection results, as well as asynchronous execution. A new generic \IQuery\<TResult\>\ interface defines the return type for queries, eliminating the need for cumbersome casting. The \IQueryExecutor\ and \IQueryHandler\ interfaces now include \ExecuteSingle\/\ExecuteSingleAsync\ methods to handle single-result queries, alongside the existing collection methods. Additionally, async variants (\ExecuteAsync\, \ExecuteSingleAsync\) are added for .NET 4.5+ environments, allowing query handlers to be released from the IoC container after use.

src/CoreDdd/Queries · medium confidence

Manual factory implementations for Ninject IoC container

The Ninject integration now uses custom factory classes (CommandHandlerFactory, QueryHandlerFactory, DomainEventHandlerFactory) to manage component lifecycles. This change addresses the lack of built-in support for releasing components from typed factories in Ninject, ensuring proper resource cleanup and preventing memory leaks.

src/CoreDdd.Register.Ninject · medium confidence

Ninject IoC bindings for NHibernate repository and unit of work

Added new Ninject-specific registration classes (CoreDddNhibernateBindings and UnitOfWorkFactory) that configure the NHibernate repository and unit of work within the Ninject container. The bindings register generic and non-generic repository interfaces with the NhibernateRepository implementation, and provide a custom UnitOfWorkFactory to handle Ninject's lack of built-in release support for typed factories.

src/CoreDdd.Nhibernate.Register.Ninject · medium confidence

Refactored command execution to use an abstract factory and support async handlers

The command handling infrastructure in src/CoreDdd/Commands was refactored to replace the previous service locator pattern with an abstract factory (ICommandHandlerFactory), which improves testability and decouples the CommandExecutor from specific IoC containers. The change introduces support for asynchronous command handlers (ExecuteAsync) on .NET 4.0+ platforms, while maintaining synchronous execution for older frameworks. Additionally, the CommandExecuted event was simplified and moved into the base handler class, allowing handlers to raise events more cleanly.

src/CoreDdd/Commands · high confidence

Removed obsolete DDD core infrastructure files

The abstract Identity base class and the AssemblyInfo metadata file have been removed from the DddCore project. This cleanup eliminates legacy identity management logic and assembly metadata that are no longer required for the domain model.

DddCore · high confidence

Repository interfaces now support generic ID types and include explicit load methods

The repository abstraction has been refactored to support generic ID types rather than hardcoding integer IDs. A new generic interface, IRepository\<TAggregateRoot, TId\>, defines core operations (Get, LoadById, Load, Save, Delete) and their async counterparts. Additionally, a specialized interface, IRepositoryInt\<TAggregateRoot\>, is introduced for integer IDs, while the existing IRepository\<TAggregateRoot\> now defaults to long IDs. This change provides more flexible repository signatures and introduces explicit loading methods that throw exceptions when entities are not found.

src/CoreDdd/Domain/Repositories · high confidence

Support for delayed domain event handling

The domain event system now supports delayed handling, allowing domain events to be processed in a separate transaction to keep the main command handling transaction shorter. This is enabled by the new \DomainEvents.RaiseDelayedEvents()\ method and the \DomainEvents.Initialize()\ configuration. When enabled, events are queued and processed later, which can improve performance by reducing transaction duration. The change also introduces \IDomainEventHandlerFactory\ for creating and releasing handlers, and adds \ResetDelayedEventsStorage()\ to clear the queue at the start of each request or transaction.

src/CoreDdd/Domain/Events · high confidence

Test coverage

Added ASP.NET integration tests for unit of work and transaction scope HTTP modules; Added integration test for persisting entities with components; Added integration tests for Nhibernate repository operations; Added persistence tests for non-integer entity IDs; Added test infrastructure for PostgreSQL, SQL Server, and SQLite persistence; Added tests for ASP.NET Core middleware transaction scope and unit of work behaviors; Added tests for AmbientStorage thread-safety and context propagation; Added tests for NHibernate Unit of Work commit behavior; Added tests for NHibernate Unit of Work transaction and disposal behavior; Added tests for NHibernate persistence conventions; Added tests for NhibernateUnitOfWorkRunner; Added tests for Rebus unit of work scenarios; Added tests for async command execution and handler lifecycle; Added tests for committing and rolling back Unit of Work within TransactionScope; Added tests for domain event handling scenarios; Added tests for entity equality across multiple ID types; Added tests for rolling back Unit of Work within Transaction Scopes; Added tests for single-result query execution in NHibernate; Added unit tests for Castle Windsor integration; Added unit tests for Guard.Hope validation logic; Added unit tests for IoC container lifecycle and resolution; Added unit tests for Ninject container operations; Added unit tests for collection extension methods; Removed legacy AssemblyInfo files from test projects.

Dependencies

Updated test and library project files with modern .NET SDK-style formatting and updated dependencies

The .csproj files for the CoreDdd library and its associated test projects have been converted to the modern SDK-style format. This update includes adding support for newer .NET target frameworks (such as net8.0 and net9.0) alongside existing .NET Framework versions. Additionally, test dependencies like NUnit, Shouldly, and Microsoft.NET.Test.Sdk have been updated to their latest stable versions, and unused references have been removed to streamline the build process.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 51 → 51 (+0.5)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 64 → 63 (-1.0)
  • Architecture 98 → 98 (+0.0)
  • Maturity 48 → 52 (+4.1)
  • Readiness 38 → 38 (-0.1)
  • Security 71 → 67 (-4.3)
  • Event-Driven 100 → 100 (+0.0)

Resolved (8)

  • Bounded contexts not declared
  • LLM evaluation failed
  • No exposed public API
  • Off-boarding risk: anonymized user #1
  • The README links to 'CoreDdd.AspNetCore' but no architecture or usage documentation is present.
  • The README links to a GitHub wiki/wiki page for 'CoreDdd documentation' (https://github.com/xhafan/coreddd/wiki) and samples, but there is no local README describing what each package does or how they fit together in the project.
  • XML-doc coverage: CoreDdd.Nhibernate.TestHelpers(net40) (src/CoreDdd.Nhibernate.TestHelpers/CoreDdd.Nhibernate.TestHelpers.csproj)
  • XML-doc coverage: CoreDdd.TestHelpers(net40) (src/CoreDdd.TestHelpers/CoreDdd.TestHelpers.csproj)

New (17)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no licence statement (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (12 lines × 2) (src/CoreDdd.AspNetCore/Middlewares/TransactionScopeUnitOfWorkMiddleware.cs)
  • Duplicated block (7 lines × 2) (src/CoreDdd.Nhibernate.Register.Castle/AddTypedFactoryFacilityHelper.cs)
  • Duplicated block (7 lines × 2) (src/CoreDdd.Nhibernate.Register.ServiceProvider/CoreDddNhibernateRegistrator.cs)
  • Duplicated block (7 lines × 2) (src/CoreDdd.Nhibernate/Conventions/DisableLazyLoadForDtosConvention.cs)
  • EmptyCatchBlock (src/CoreDdd.Nhibernate/UnitOfWorks/NhibernateUnitOfWork.cs)
  • EmptyCatchBlock (src/CoreDdd.Nhibernate/UnitOfWorks/NhibernateUnitOfWork.cs)
  • End-of-life runtime: .NET Framework net461
  • End-of-life runtime: .NET net9.0
  • End-of-life runtime: .NET netcoreapp3.1
  • Inconsistent spelling of the word 'retrieved'. One test method uses 'retreieved' (typo), while another uses 'retrieved' (correct).
  • No assertions: calling_dispose_after_commit_is_safe (src/CoreDdd.Nhibernate.Tests/UnitOfWorks/Committing/when_committing_unit_of_work.cs)
  • Test cannot fail: unit_of_work_can_be_gracefully_disposed (src/CoreDdd.Nhibernate.Tests/UnitOfWorks/when_starting_transaction_fails.cs)
  • TodoComment (src/CoreDdd.Nhibernate/UnitOfWorks/NhibernateUnitOfWork.cs)
  • redundant comment (src/IntegrationTestsShared/TransactionScopes/VolatileResourceManager.cs)

Architecture

  • Unchanged — 1 containers · 1 contexts · 0 edges

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

xhafan/coreddd was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 07a76c5c92b946f15e2aeb9281abb42147065e0e — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.