Header menu logo FCQRS

Running the Program

We start as usual. Make sure you get proper lastKnownOffset. This is the last offset value that was persisted to the database.

let lastKnownOffset = 0L
let sub = Bootstrap.sub Query.handleEventWrapper lastKnownOffset

let cid (): CID =
    System.Guid.NewGuid().ToString() |> ValueLens.CreateAsResult |> Result.value

let userName = "testuser"

let password = "password"

let cid1 = cid()

let s = sub.Subscribe((fun e -> e.CID = cid1), 1)
let result = register cid1 userName password |> Async.RunSynchronously
(s |> Async.RunSynchronously).Dispose()
printfn "%A" result

Now we read the code from terminal. We should observe the mail already sent

let code = System.Console.ReadLine() 

Observe verification

let resultVerify = verify (cid()) userName code |> Async.RunSynchronously
printfn "%A" resultVerify

System.Console.ReadKey() |> ignore

Try registering the same user again.

let resultFailure = register (cid()) userName password |> Async.RunSynchronously
printfn "%A" resultFailure

System.Console.ReadKey() |> ignore

Login the user with incorrect password.

let loginResultF = login (cid()) userName "wrong pass" |> Async.RunSynchronously
printfn "%A" loginResultF

Login the user with correct password.

let loginResultS = login (cid()) userName password |> Async.RunSynchronously
printfn "%A" loginResultS
System.Console.ReadKey() |> ignore

Summary

In this example, we have shown how to use the FCQRS library to implement a simple user registration and login system with email verification. We have also shown how to use the FCQRS library to implement a simple user registration and login system with email verification.

namespace System
namespace System.IO
namespace Microsoft
namespace Microsoft.Extensions
namespace Microsoft.Extensions.Configuration
namespace Hocon
namespace Hocon.Extensions
namespace Hocon.Extensions.Configuration
module Bootstrap
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
module Command

--------------------
type Command<'CommandDetails> = { CommandDetails: 'CommandDetails CreationDate: DateTime Id: MessageId option Sender: ActorId option CorrelationId: CID } interface IMessageWithCID interface ISerializable member Equals: Command<'CommandDetails> * IEqualityComparer -> bool override ToString: unit -> string
<summary> Represents a command to be processed by an aggregate actor. &lt;typeparam name="'CommandDetails"&gt;The specific type of the command payload.&lt;/typeparam&gt; </summary>

--------------------
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>
val lastKnownOffset: int64
val sub: FCQRS.Query.ISubscribe<IMessageWithCID>
val sub: handleEventWrapper: (Environments.AppEnv -> int64 -> obj -> 'a list) -> offsetCount: int64 -> FCQRS.Query.ISubscribe<'a>
module Query
val handleEventWrapper: env: ILoggerFactoryWrapper -> offsetValue: int64 -> event: obj -> IMessageWithCID list
val cid: unit -> CID
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
[<Struct>] type Guid = new: b: byte array -> unit + 6 overloads member CompareTo: value: Guid -> int + 1 overload member Equals: g: Guid -> bool + 1 overload member GetHashCode: unit -> int member ToByteArray: unit -> byte array + 1 overload member ToString: unit -> string + 2 overloads member TryFormat: utf8Destination: Span<byte> * bytesWritten: byref<int> * ?format: ReadOnlySpan<char> -> bool + 1 overload member TryWriteBytes: destination: Span<byte> -> bool + 1 overload static member (<) : left: Guid * right: Guid -> bool static member (<=) : left: Guid * right: Guid -> bool ...
<summary>Represents a globally unique identifier (GUID).</summary>

--------------------
System.Guid ()
System.Guid(b: byte array) : System.Guid
System.Guid(b: System.ReadOnlySpan<byte>) : System.Guid
System.Guid(g: string) : System.Guid
System.Guid(b: System.ReadOnlySpan<byte>, bigEndian: bool) : System.Guid
System.Guid(a: int, b: int16, c: int16, d: byte array) : System.Guid
System.Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : System.Guid
System.Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : System.Guid
System.Guid.NewGuid() : System.Guid
type ValueLens = static member Create: innerValue: 'Inner -> 'Wrapped (requires member Value_) static member CreateAsResult: v: 'a -> Result<'b,'d> (requires member Value_ and member Value_) static member IsValidValue: this: 'Wrapped -> bool (requires member Value_) static member Isvalid: this: 'a -> bool (requires member Value_ and member Value_) static member ToString: this: 'Wrapped -> string (requires member Value_) static member TryCreate: innerValue: 'Inner -> Result<'Wrapped,'Error> (requires member Value_) static member Value: this: 'Wrapped -> 'Inner (requires member Value_) + 1 overload
static member ValueLens.CreateAsResult: v: 'a -> Result<'b,'d> (requires member Value_ and member Value_)
Multiple items
module Result from FCQRS.Model.Data

--------------------
module Result from Microsoft.FSharp.Core

--------------------
[<Struct>] type Result<'T,'TError> = | Ok of ResultValue: 'T | Error of ErrorValue: 'TError
val value: e: Result<'a,'b> -> 'a
val userName: string
val password: string
val cid1: CID
val s: FCQRS.Query.IAwaitableDisposable
abstract FCQRS.Query.ISubscribe.Subscribe: callback: ('TDataEvent -> unit) * ?cancellationToken: System.Threading.CancellationToken -> System.IDisposable
abstract FCQRS.Query.ISubscribe.Subscribe: filter: ('TDataEvent -> bool) * take: int * ?callback: ('TDataEvent -> unit) * ?cancellationToken: System.Threading.CancellationToken -> FCQRS.Query.IAwaitableDisposable
val e: IMessageWithCID
property IMessageWithCID.CID: CID with get
<summary> Gets the Correlation ID associated with the message. </summary>
val result: Result<Version,string list>
val register: cid: CID -> userName: string -> password: string -> Async<Result<Version,string list>>
Multiple items
type Async = static member AsBeginEnd: computation: ('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) static member AwaitEvent: event: IEvent<'Del,'T> * ?cancelAction: (unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate) static member AwaitIAsyncResult: iar: IAsyncResult * ?millisecondsTimeout: int -> Async<bool> static member AwaitTask: task: Task<'T> -> Async<'T> + 1 overload static member AwaitWaitHandle: waitHandle: WaitHandle * ?millisecondsTimeout: int -> Async<bool> static member CancelDefaultToken: unit -> unit static member Catch: computation: Async<'T> -> Async<Choice<'T,exn>> static member Choice: computations: Async<'T option> seq -> Async<'T option> static member FromBeginEnd: beginAction: (AsyncCallback * obj -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> ...

--------------------
type Async<'T>
static member Async.RunSynchronously: computation: Async<'T> * ?timeout: int * ?cancellationToken: System.Threading.CancellationToken -> 'T
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
val code: string
type Console = static member Beep: unit -> unit + 1 overload static member Clear: unit -> unit static member GetCursorPosition: unit -> struct (int * int) static member MoveBufferArea: sourceLeft: int * sourceTop: int * sourceWidth: int * sourceHeight: int * targetLeft: int * targetTop: int -> unit + 1 overload static member OpenStandardError: unit -> Stream + 1 overload static member OpenStandardInput: unit -> Stream + 1 overload static member OpenStandardOutput: unit -> Stream + 1 overload static member Read: unit -> int static member ReadKey: unit -> ConsoleKeyInfo + 1 overload static member ReadLine: unit -> string ...
<summary>Represents the standard input, output, and error streams for console applications. This class cannot be inherited.</summary>
System.Console.ReadLine() : string
val resultVerify: Result<Version,string list>
val verify: cid: CID -> userName: string -> code: string -> Async<Result<Version,string list>>
System.Console.ReadKey() : System.ConsoleKeyInfo
System.Console.ReadKey(intercept: bool) : System.ConsoleKeyInfo
val ignore: value: 'T -> unit
val resultFailure: Result<Version,string list>
val loginResultF: Result<Version,string list>
val login: cid: CID -> userName: string -> password: string -> Async<Result<Version,string list>>
val loginResultS: Result<Version,string list>

Type something to start searching.