Skip to content

Instantly share code, notes, and snippets.

@mavnn
Created September 16, 2016 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mavnn/1a4fb7f625b56f05b204a84546386fc9 to your computer and use it in GitHub Desktop.
Save mavnn/1a4fb7f625b56f05b204a84546386fc9 to your computer and use it in GitHub Desktop.
// Fakes to make things look nice
type Category = Category
type Id = Id
type ReCQSettings = ReCQSettings
type EsAction<'a> = EsAction of 'a
type Version = Version of uint32
type ExpectedVersionUnion =
| Any
| Specific of uint32
| NoStream
| EmptyStream
type WriteResult =
| Success
| Failure of System.Exception
| ConcurrencyFailure
let writeToEventStore events expectedVersion : WriteResult =
Success
type CommandWriteResult<'Event> =
| Success of Version * 'Event list
| Failure of System.Exception
/// Should this be called aggregate? People might want to call the
/// aggregate they're loading the aggregate
type Aggregate<'State, 'Command, 'Event> =
{ zero : 'State
apply : 'State -> 'Event -> 'State
exec : 'State -> 'Command -> 'Event list
category : Category
generator : 'Event -> Id }
/// This needs a better name
type ConfiguredAggregateRepo<'State, 'Command, 'Event> =
abstract member read : Id -> EsAction<Version * 'State * ExpectedVersionUnion>
abstract member write : Id -> 'Command -> EsAction<CommandWriteResult<'Event>>
[<RequireQualifiedAccess; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Aggregate =
/// sets up all the behind the scenes stuff...
let configureAggregateRepo (aggregate : Aggregate<'State, 'Command, 'Event>)
(settings : ReCQSettings) (ser, deser) : ConfiguredAggregateRepo<_,_,_> =
{ new ConfiguredAggregateRepo<'State,'Command,'Event> with
member x.read aid =
EsAction (Version 1u, aggregate.zero, Specific 0u)
member x.write aid command =
let (EsAction(Version v, state, expected)) = x.read aid
let events = aggregate.exec state command
let newVersion = (uint32 <| List.length events) + v |> Version
match writeToEventStore events expected with
| WriteResult.Success -> Success (newVersion, events) |> EsAction
| WriteResult.Failure e -> Failure e |> EsAction
| WriteResult.ConcurrencyFailure ->
x.write aid command }
[<RequireQualifiedAccess; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module ConfiguredAggregateRepo =
let read (car : ConfiguredAggregateRepo<_,_,_>) aid =
car.read aid
let write (car : ConfiguredAggregateRepo<_,_,_>) aid command =
car.write aid command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment