Table of Contents

Class DecisionProjection<TState>

Namespace
Opossum.DecisionModel
Assembly
Opossum.dll

Delegate-based implementation of IDecisionProjection<TState>. Provides a concise way to define decision model projections via lambda expressions, enabling the factory function pattern recommended by the DCB Projections specification.

public sealed class DecisionProjection<TState> : IDecisionProjection<TState>

Type Parameters

TState

The type that represents the decision model state. May be a value type (e.g. bool, int) or a reference type.

Inheritance
DecisionProjection<TState>
Implements
Inherited Members

Remarks

Typical usage via a static factory method on the domain layer:

public static class CourseProjections
{
    public static IDecisionProjection<bool> CourseExists(Guid courseId) =>
        new DecisionProjection<bool>(
            initialState: false,
            query: Query.FromItems(new QueryItem
            {
                EventTypes = [nameof(CourseCreatedEvent)],
                Tags = [new Tag("courseId", courseId.ToString())]
            }),
            apply: (state, evt) => evt.Event.Event is CourseCreatedEvent ? true : state);
public static IDecisionProjection<int> EnrollmentCount(Guid courseId) =>
    new DecisionProjection<int>(
        initialState: 0,
        query: Query.FromItems(new QueryItem
        {
            EventTypes = [nameof(StudentEnrolledToCourseEvent)],
            Tags = [new Tag("courseId", courseId.ToString())]
        }),
        apply: (state, evt) => evt.Event.Event is StudentEnrolledToCourseEvent
            ? state + 1
            : state);

}

Constructors

DecisionProjection(TState, Query, Func<TState, SequencedEvent, TimeProvider, TState>, TimeProvider?)

Creates a time-aware DecisionProjection<TState> whose fold function receives the current time from a TimeProvider. Defaults to System in production. Inject a custom TimeProvider in tests to control wall-clock time.

public DecisionProjection(TState initialState, Query query, Func<TState, SequencedEvent, TimeProvider, TState> apply, TimeProvider? timeProvider = null)

Parameters

initialState TState

The starting state before any events are applied.

query Query

The query that selects relevant events and guards the append condition.

apply Func<TState, SequencedEvent, TimeProvider, TState>

A pure function that folds a single event into the current state using a TimeProvider to access the current time.

timeProvider TimeProvider

The time provider used to get "now" during folding. Defaults to System when null.

Exceptions

ArgumentNullException

Thrown when query or apply is null.

DecisionProjection(TState, Query, Func<TState, SequencedEvent, TState>)

public DecisionProjection(TState initialState, Query query, Func<TState, SequencedEvent, TState> apply)

Parameters

initialState TState

The starting state before any events are applied.

query Query

The query that selects relevant events and guards the append condition.

apply Func<TState, SequencedEvent, TState>

A pure function that folds a single event into the current state.

Exceptions

ArgumentNullException

Thrown when query or apply is null.

Properties

InitialState

The starting state before any events are applied.

public TState InitialState { get; }

Property Value

TState

Query

The query that selects events relevant to this projection from the event store. This same query is used as FailIfEventsMatch to guard the decision against concurrent writes — ensuring the decision model is still valid at the moment of appending.

public Query Query { get; }

Property Value

Query

Methods

Apply(TState, SequencedEvent)

Folds a single event into the current state. Must be a pure function with no side effects.

public TState Apply(TState state, SequencedEvent evt)

Parameters

state TState

The current accumulated state.

evt SequencedEvent

The next sequenced event to apply.

Returns

TState

The new state after applying the event.