Header menu logo FCQRS

Commands

Both Commands and Events are actor messages. The difference is semantic whereas a command represents something that is requested to be done, an event represents something that has already happened. We don't persist the commands but only events. In your aggregates you define your commands as plain discriminated unions. But they they are auto wrapped into FCQRS commands which have additional metadata.

type Command<'CommandDetails> =
    { CommandDetails: 'CommandDetails
      CreationDate: DateTime
      Id: MessageId option
      Sender: ActorId option
      CorrelationId: CID }

You typically provide the CID which is a guid-like string and the command details which is your command object. Rest of the details are filled in by the framework. The command is then sent to the actor.

Events

Events are also actor messages. They are also auto wrapped in to FCQRS events which have additional metadata. The events are persisted in the event store. The events are also wrapped in a discriminated union. Events represent something that has already happened. Their CID's and Id's auto copied from the commands. You can also see they have a version property. Everytime an event is persisted, the aggregates version is incremented.

type Event<'EventDetails> =
    { EventDetails: 'EventDetails
      CreationDate: DateTime
      Id: MessageId option
      Sender: ActorId option
      CorrelationId: CID
      Version: Version }
namespace System
namespace System.IO
namespace Microsoft
namespace Microsoft.Extensions
namespace Microsoft.Extensions.Configuration
namespace Hocon
namespace Hocon.Extensions
namespace Hocon.Extensions.Configuration
namespace FCQRS
module Common from FCQRS
<summary> Contains common types like Events and Commands </summary>
<namespacedoc><summary>Functionality for Write Side.</summary></namespacedoc>
namespace FCQRS.Model
module Data from FCQRS.Model
Multiple items
type Command<'CommandDetails> = { CommandDetails: 'CommandDetails CreationDate: DateTime Id: MessageId option Sender: ActorId option CorrelationId: CID }

--------------------
type Command<'Command,'Event> = | Execute of CommandDetails<'Command,'Event>
<summary> Represents the message sent to the internal subscription mechanism. &lt;typeparam name="'Command"&gt;The type of the command payload.&lt;/typeparam&gt; &lt;typeparam name="'Event"&gt;The type of the expected event payload.&lt;/typeparam&gt; </summary>
type CommandDetails<'Command,'Event> = { EntityRef: IEntityRef<obj> Cmd: Command<'Command> Filter: ('Event -> bool) }
Multiple items
type CommandDetails<'Command,'Event> = { EntityRef: IEntityRef<obj> Cmd: Command<'Command> Filter: ('Event -> bool) }

--------------------
'CommandDetails
Multiple items
[<Struct>] type DateTime = new: date: DateOnly * time: TimeOnly -> unit + 16 overloads member Add: value: TimeSpan -> DateTime member AddDays: value: float -> DateTime member AddHours: value: float -> DateTime member AddMicroseconds: value: float -> DateTime member AddMilliseconds: value: float -> DateTime member AddMinutes: value: float -> DateTime member AddMonths: months: int -> DateTime member AddSeconds: value: float -> DateTime member AddTicks: value: int64 -> DateTime ...
<summary>Represents an instant in time, typically expressed as a date and time of day.</summary>

--------------------
DateTime ()
   (+0 other overloads)
DateTime(ticks: int64) : DateTime
   (+0 other overloads)
DateTime(date: DateOnly, time: TimeOnly) : DateTime
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(date: DateOnly, time: TimeOnly, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : DateTime
   (+0 other overloads)
type MessageId = private | MessageId of ShortString member Equals: MessageId * IEqualityComparer -> bool override ToString: unit -> string member IsValid: bool static member Value_: (MessageId -> ShortString) * (ShortString -> MessageId -> MessageId)
<summary> Message Id , generally not much use case. </summary>
type 'T option = Option<'T>
union case TargetActor.Sender: TargetActor
<summary> Specifies the target as the original sender of the message that triggered the current saga step. </summary>
type ActorId = private | ActorId of ShortString member Equals: ActorId * IEqualityComparer -> bool override ToString: unit -> string member IsValid: bool static member Value_: (ActorId -> ShortString) * (ShortString -> ActorId -> ActorId)
type CID = private | CID of ShortString member Equals: CID * IEqualityComparer -> bool override ToString: unit -> string member IsValid: bool static member Value_: (CID -> ShortString) * (ShortString -> CID -> CID)
<summary> CorrelationID for commands and Sagas </summary>
Multiple items
module Event from Microsoft.FSharp.Control

--------------------
type Event<'EventDetails> = { EventDetails: 'EventDetails CreationDate: DateTime Id: MessageId option Sender: ActorId option CorrelationId: CID Version: Version }

--------------------
type Event<'Delegate,'Args (requires delegate and 'Delegate :> Delegate and reference type)> = new: unit -> Event<'Delegate,'Args> member Trigger: sender: obj * args: 'Args -> unit member Publish: IEvent<'Delegate,'Args>

--------------------
new: unit -> Event<'Delegate,'Args>
'EventDetails
type Version = private | Version of int64 member Equals: Version * IEqualityComparer -> bool override ToString: unit -> string static member Value_: (Version -> int64) * (int64 -> Version -> Result<Version,ModelError>) static member Zero: Version
<summary> Aggregate Version </summary>

Type something to start searching.