ircnelson/enjoy.cqrs
48.2
Weak · 21 September 2026
6k
lines of production code
C#
primary language
4
measurements over time
What this system is
EnjoyCQRS is a CQRS and event sourcing framework that provides infrastructure for managing domain events, command dispatching, and aggregate state management. It supports pluggable event and snapshot storage, with specific implementations for MongoDB and in-memory stores, alongside a dependency injection integration for Autofac. The system also includes tools for handling event metadata, projections, and unit testing.
How it got here
2016 — CQRS and Event Sourcing Architecture
32 changes.
This period focused on establishing a robust CQRS and event-sourcing foundation, introducing core abstractions for commands, events, and message buses. The work included implementing key features like aggregate snapshotting, event metadata, and asynchronous storage interfaces, while simultaneously building out comprehensive test coverage and CI/CD infrastructure to support the new architecture.
2017 — MongoDB integration and projection support
9 changes.
This period focused on expanding the framework's storage capabilities by introducing MongoDB-based event and snapshot stores, alongside in-memory alternatives for testing. It also added support for CQRS projections, including an in-memory projector and MongoDB-specific projection readers and writers, accompanied by comprehensive unit and integration tests.
Features
Add MongoDB projection store and reader/writer implementations
The MongoDB event store now includes new classes for handling projections: MongoEventStreamReader, MongoProjectionReaderWriter, MongoProjectionStore, and MongoProjectionStrategy. These classes implement reading events from MongoDB collections, managing projection state in temporary and permanent collections, and serializing/deserializing projection data using BSON/JSON. This adds support for storing and querying projected data in MongoDB, enabling CQRS projections to be persisted and retrieved via MongoDB.
src/EnjoyCQRS.EventStore.MongoDB/Projection · high confidence
Added Autofac integration for external dependency injection
Users can now use the Autofac container to manage dependency injection within the CQRS framework. This change introduces the \EnjoyCQRS.DependencyInjection.Autofac\ module, which provides an \AutofacEnjoyDependenciesBuilder\ to register core components like the command dispatcher, event router, and event store with Autofac's lifetime scopes. The \ContainerBuilderExtension\ offers a convenient \UseEnjoyCQRS\ extension method to bootstrap the framework, allowing developers to wire up their own implementations or use the default in-memory stores and handlers through the Autofac container.
src/EnjoyCQRS.DependencyInjection.Autofac · high confidence
Added CI/CD and build infrastructure
The project now includes a complete build and continuous integration setup. A Cake build script (build.cake) and its PowerShell/Shell bootstrappers (build.ps1, build.sh) automate building, testing, and packaging. Continuous integration is configured for both AppVeyor (appveyor.yml) and Travis CI (.travis.yml), which run tests and publish coverage reports. The solution file (EnjoyCQRS.sln) is structured to organize the codebase into src and test folders, and a .gitignore file is added to manage version control artifacts.
(repo-wide) · high confidence
Added MongoDB-based event and snapshot storage
Introduced new implementations for the event and snapshot stores using MongoDB. The \MongoEventStore\ handles persisting and retrieving domain events, while \MongoSnapshotStore\ manages aggregate snapshots. These are wired together via the \MongoStores\ composite store, which coordinates transactional commits for both events and snapshots, and triggers projection rebuilding after event persistence.
src/EnjoyCQRS.EventStore.MongoDB/Stores · high confidence
Added ValueObject base class for value-based equality
A new abstract ValueObject base class has been introduced in the EnjoyCQRS project. This class provides a standard implementation for value-based equality, overriding Equals, GetHashCode, and equality operators to ensure that instances are compared by their field values rather than by reference identity.
src/EnjoyCQRS/ValueObjects · high confidence
Added in-memory implementations for event and snapshot stores
The codebase now includes in-memory implementations for the event store (InMemoryEventStore), snapshot store (InMemorySnapshotStore), and a composite store (InMemoryStores) that manages transactions, commits, and rollbacks for both events and snapshots in memory.
src/EnjoyCQRS/Stores · high confidence
Added in-memory projection store and projector wiring for event-driven projections
Developers can now use an in-memory implementation of the projection store (MemoryProjectionStore) and a new EventStreamReader to handle event streams. The update introduces IProjectionStore, IProjectionReader, IProjectionWriter, and IProjectionRebuilder interfaces, along with a ProjectorMethodMapper that dynamically wires projector methods to handle events and metadata. This enables in-memory testing and prototyping of CQRS projections without requiring a persistent storage backend.
src/EnjoyCQRS/Projections · high confidence
Added metadata providers and logging extensions
The library now includes a metadata provider system with new implementations for aggregate type, event type, and correlation ID, alongside extension methods for logging and domain events. This enables automatic enrichment of events with structured metadata and standardized logging levels.
src/EnjoyCQRS/Extensions · high confidence
Introduce event metadata, aggregate, and unit-of-work abstractions
The EventSource area now includes new abstractions and implementations for managing event metadata and unit-of-work transactions. This includes the IMetadataCollection and MetadataCollection for storing and merging event metadata, the EventMetadataItem and EventsMetadataService to retrieve all metadata of events in a transaction, and the IAggregate interface to track uncommitted events and versioning. Additionally, the UnitOfWork class provides transactional commit and rollback support, while the Route class allows optional or mandatory event handling.
src/EnjoyCQRS/EventSource · medium confidence
Introduce snapshotting infrastructure for aggregates
Added the core types and strategies for aggregate snapshotting. This includes the ISnapshot interface and abstract Snapshot base class, along with ICommittedSnapshot and IUncommittedSnapshot interfaces that carry aggregate ID, version, and metadata. The default snapshot strategy (DefaultSnapshotStrategy) checks if an aggregate supports snapshots, while the interval-based strategy (IntervalSnapshotStrategy) triggers snapshots at configurable event intervals. The SnapshotRestore class provides a concrete implementation of ISnapshotRestore for restoring aggregate state from a snapshot.
src/EnjoyCQRS/EventSource/Snapshots · high confidence
Introduces a new logging abstraction for the application
A new logging subsystem has been added to the codebase, providing a standardized way to record application events. This includes the \ILogger\ and \ILoggerFactory\ interfaces, a \LogLevel\ enumeration for severity levels (Trace through Critical), and a \NoopLogger\ implementation that discards all log messages. This change allows the application to decouple its internal logging mechanisms from specific implementations, enabling easier testing and future integration with external logging services.
src/EnjoyCQRS/Logger · high confidence
Introduces message bus abstractions and in-process event publishing
The message bus implementation now exposes explicit interfaces for command dispatching (ICommandDispatcher) and event publishing/routing (IEventPublisher, IEventRouter), alongside a concrete InProcess EventPublisher that queues and routes domain events. This refactors the previous Bus folder into MessageBus and adds a CommandDispatcher to encapsulate command routing details, providing a cleaner, more testable API for sending commands and publishing events within the application.
src/EnjoyCQRS/MessageBus · high confidence
New dependency injection and event update infrastructure
The core library introduces a new, fluent API for registering and validating dependencies (EventStore, CommandDispatcher, UnitOfWork, etc.) via the \EnjoyDependenciesBuilder\. This replaces the previous serialization abstraction and adds support for external container wiring. Additionally, the framework now supports updating event structures before aggregate replay through the new \IEventUpdate\ and \IEventUpdateManager\ interfaces, allowing developers to migrate or transform legacy events. A generic \Metadata\<T\>\ class is also added to attach key-value metadata to domain events.
src/EnjoyCQRS/Core · high confidence
New event interfaces and internal event model
The library introduces a new eventing architecture with dedicated interfaces for domain events (IDomainEvent), committed events (ICommittedEvent), and uncommitted events (IUncommittedEvent), each carrying metadata and versioning information. An internal UncommittedEvent class implements the IUncommittedEvent interface, providing a concrete model for events before they are persisted. This change establishes the foundation for the new in-process CommandBus and EventBus implementation.
src/EnjoyCQRS/Events · high confidence
New exception types for event sourcing errors
The library now provides specific exception classes to handle common event sourcing scenarios, including \AggregateNotFoundException\ for missing aggregates, \EventTypeNotFoundException\ for unknown event types during deserialization, \ExpectedVersionException\ for concurrency/optimistic locking conflicts, and \HandleNotFound\ for unhandled event types. These changes allow developers to catch and handle these distinct error conditions more precisely.
src/EnjoyCQRS/EventSource/Exceptions · medium confidence
New test fixtures for aggregate, command, and event handling scenarios
The test framework now provides three new abstract test fixture classes to simplify writing unit tests for the CQRS components. AggregateTestFixture allows testing aggregate root behavior by executing a 'When' step and capturing published domain events. CommandTestFixture enables testing command handlers by mocking dependencies (such as repositories) and executing commands asynchronously. EventTestFixture facilitates testing event handlers by allowing dependency mocking and capturing any exceptions thrown during event processing. These fixtures standardize the test setup and execution flow for the EnjoyCQRS library.
src/EnjoyCQRS.TestFramework · high confidence
Support for domain event metadata and aggregate snapshots
The library now supports attaching arbitrary metadata to domain events via the new \IEventWrapper\ interface and \Event\<T\>\ class, allowing users to publish events with associated attributes. Additionally, the framework introduces a snapshotting mechanism for aggregates, providing the \SnapshotAggregate\<T\>\ base class and \ISnapshotAggregate\ interface to save and restore aggregate state efficiently.
EnjoyCQRS · high confidence
Behavioural changes
Added assembly metadata for the MongoDB event store component
The MongoDB event store library now includes explicit assembly metadata (company and product names) in its compiled output, ensuring that the library correctly identifies itself as part of the EnjoyCQRS ecosystem when inspected via reflection or package managers.
src/EnjoyCQRS.EventStore.MongoDB/Properties · high confidence
Exposes internal members to unit tests
The assembly now exposes its internal members to the 'EnjoyCQRS.UnitTests' assembly via an InternalsVisibleTo attribute, allowing the unit test suite to access internal types and members for testing purposes.
src/EnjoyCQRS/Properties · high confidence
Introduce MongoDB event store models and settings
Added new data models for the MongoDB event store implementation, including document classes for events and snapshots, as well as a configuration class that defines the default collection names for events, snapshots, and projections.
src/EnjoyCQRS.EventStore.MongoDB · medium confidence
Introduced base Command and handler interfaces for CQRS
Added new abstractions for the command pattern: an abstract Command base class that enforces an AggregateId, an ICommand marker interface, and an ICommandHandler interface defining the ExecuteAsync method. This refactors the existing command handling structure to support asynchronous execution and clearer separation of concerns within the CQRS implementation.
src/EnjoyCQRS/Commands · high confidence
Introduces asynchronous repository and session abstractions for event sourcing
The storage layer now exposes \IRepository\ and \ISession\ interfaces that operate asynchronously (\GetByIdAsync\, \AddAsync\), allowing the \Repository\ and \Session\ classes to perform event loading, snapshot restoration, and state tracking without blocking threads. This change enables non-blocking access to aggregate state and event streams, improving scalability for event-sourced applications.
src/EnjoyCQRS/EventSource/Storage · high confidence
Test coverage
Added Web API integration tests for command handling; Added integration tests for MongoDB event store and projections; Added stub application and test utilities for unit testing; Added test infrastructure for event store validation; Added test stubs for aggregate and snapshot behavior; Added test stubs for domain events; Added test stubs for message bus event handling; Added unit tests for Autofac dependency registration; Added unit tests for CQRS handlers; Added unit tests for aggregate domain logic; Added unit tests for in-memory projection storage and reader/writer implementations; Added unit tests for metadata collection and providers; Added unit tests for storage components; Added unit tests for the EventUpgrader component; Added unit tests for the ValueObject abstraction; Added unit tests for the dependency injection builder; Added unit tests for the message bus components; Added unit tests for the new snapshotting feature.
Dependencies
Updated test framework and dependency packages
The project's test framework and related dependencies have been updated. The test framework version has been upgraded, and several packages including xUnit, Moq, and FluentAssertions have been updated to their latest compatible versions to support the new test infrastructure.
(dependencies) · medium 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
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 49 → 48 (-0.9)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 63 → 61 (-2.2)
- Architecture 98 → 98 (+0.0)
- Maturity 51 → 51 (+0.0)
- Readiness 38 → 38 (+0.0)
- Security 67 → 56 (-10.5)
- Domain Modelling 74 → 79 (+4.3)
- Performance 60 → 60 (+0.0)
Resolved (15)
- Bounded contexts not declared
- Change coupling: IRepository.cs ↔ Session.cs (src/EnjoyCQRS/EventSource/Storage/IRepository.cs)
- Change coupling: Repository.cs ↔ Session.cs (src/EnjoyCQRS/EventSource/Storage/Repository.cs)
- Change coupling: Session.cs ↔ InMemoryStores.cs (src/EnjoyCQRS/EventSource/Storage/Session.cs)
- High CVE: Microsoft.NETCore.App 1.1.2
- High CVE: Microsoft.NETCore.App 1.1.2
- High CVE: System.Net.Security 4.0.0
- High CVE: System.Net.Security 4.0.0
- Medium CVE: System.Net.Security 4.0.0
- Medium CVE: System.Net.Security 4.0.0
- No exposed public API
- Test runner surfaced no tests
- The document body clips mid-sentence ('This framework can help you wit') before any real content appears (features/configure/environment/implementation sections), so the outlined material is not visible and cannot be verified from this single file. (README.md)
- dormant codebase — no living knowledge left to concentrate
- redundant comment (src/EnjoyCQRS.DependencyInjection.Autofac/AutofacEnjoyDependenciesBuilder.cs)
New (17)
- DeadPreprocessorBranch (src/EnjoyCQRS/ValueObjects/ValueObject.cs)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- EmptyCatchBlock (src/EnjoyCQRS/Projections/ProjectionRebuilder.cs)
- End-of-life runtime: .NET netcoreapp1.1
- High CVE: Microsoft.NETCore.App 1.1.2
- High CVE: System.Net.Security 4.0.0
- High: security finding (details withheld)
- High: security finding (details withheld)
- Inconsistent spelling of 'Snapshotting': The namespace and test class use 'Snapshoting' (single 't'), while the concept is standardly spelled 'Snapshotting' (double 't'). Additionally, the test method name 'When_aggregate_type_have_support_snapshoting()' uses the non-standard single 't' form.
- No SBOM
- No artifact signing
- No build provenance
- No dependency advisory monitoring
- Typo in type name: 'Setttings' (double 't') instead of 'Settings'. This typo is propagated to the property names within the type.
- WriteOnlyPrivateField (src/EnjoyCQRS/Logger/NoopLogger.cs)
- WriteOnlyPrivateField (src/EnjoyCQRS/Projections/ProjectorMethodMapper.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
ircnelson/enjoy.cqrs 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 3628c221b9af29439ff76a29c9cc0f7bcef4c4bf — 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.