A Walkthrough: User Registration and Login
In this example, we will create a simple user registration and login system using FCQRS. The system will consist of a User aggregate that handles commands for registering and logging in users.
The aggregate will emit events based on the commands it processes. We will also implement a simple actor that will manage the state of the User aggregate. You can find the full sample code
in the sample folder of repo.
- Create a new F# project: dotnet new console -lang F# -n MyFCQRSApp
-
Add the packages:
dotnet add package FCQRS
dotnet add package Hocon.Extensions.Configuration
dotnet add package Microsoft.Extensions.Logging.Console
- Create a hocon configuration file: config.hocon
- Create an Environments module and implement IConfiguration: and ILoggerFactory:
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.Logging
type AppEnv(config: IConfiguration, loggerFactory: ILoggerFactory) =
interface ILoggerFactory with
member _.AddProvider(provider: ILoggerProvider) : unit =
loggerFactory.AddProvider provider
member _.CreateLogger(categoryName: string) : ILogger =
loggerFactory.CreateLogger categoryName
member _.Dispose() : unit = loggerFactory.Dispose()
interface IConfiguration with
member _.Item
with get (key: string) = config.[key]
and set key v = config.[key] <- v
member _.GetChildren() = config.GetChildren()
member _.GetReloadToken() = config.GetReloadToken()
member _.GetSection key = config.GetSection key
Above code acts as a composition root for the application environment. It wraps IConfiguration and ILoggerFactory, allowing you to manage configuration and logging in a clean and type-safe manner.
namespace System
namespace System.IO
namespace Microsoft
namespace Microsoft.Extensions
namespace Microsoft.Extensions.Configuration
namespace Hocon
namespace Hocon.Extensions
namespace Hocon.Extensions.Configuration
namespace Microsoft.Extensions.Logging
Multiple items
type AppEnv = interface IConfiguration interface ILoggerFactory new: config: IConfiguration * loggerFactory: ILoggerFactory -> AppEnv
--------------------
new: config: IConfiguration * loggerFactory: ILoggerFactory -> AppEnv
type AppEnv = interface IConfiguration interface ILoggerFactory new: config: IConfiguration * loggerFactory: ILoggerFactory -> AppEnv
--------------------
new: config: IConfiguration * loggerFactory: ILoggerFactory -> AppEnv
val config: IConfiguration
type IConfiguration =
override GetChildren: unit -> IEnumerable<IConfigurationSection>
override GetReloadToken: unit -> IChangeToken
override GetSection: key: string -> IConfigurationSection
member Item: string
<summary> Represents a set of key/value application configuration properties. </summary>
<summary> Represents a set of key/value application configuration properties. </summary>
val loggerFactory: ILoggerFactory
type ILoggerFactory =
inherit IDisposable
override AddProvider: provider: ILoggerProvider -> unit
override CreateLogger: categoryName: string -> ILogger
<summary> Represents a type used to configure the logging system and create instances of <see cref="T:Microsoft.Extensions.Logging.ILogger" /> from the registered <see cref="T:Microsoft.Extensions.Logging.ILoggerProvider" />s. </summary>
<summary> Represents a type used to configure the logging system and create instances of <see cref="T:Microsoft.Extensions.Logging.ILogger" /> from the registered <see cref="T:Microsoft.Extensions.Logging.ILoggerProvider" />s. </summary>
val provider: ILoggerProvider
type ILoggerProvider =
inherit IDisposable
override CreateLogger: categoryName: string -> ILogger
<summary> Represents a type that can create instances of <see cref="T:Microsoft.Extensions.Logging.ILogger" />. </summary>
<summary> Represents a type that can create instances of <see cref="T:Microsoft.Extensions.Logging.ILogger" />. </summary>
type unit = Unit
ILoggerFactory.AddProvider(provider: ILoggerProvider) : unit
val categoryName: string
Multiple items
val string: value: 'T -> string
--------------------
type string = System.String
val string: value: 'T -> string
--------------------
type string = System.String
Multiple items
type ILogger = override BeginScope<'TState> : state: 'TState -> IDisposable override IsEnabled: logLevel: LogLevel -> bool override Log<'TState> : logLevel: LogLevel * eventId: EventId * state: 'TState * ``exception`` : exn * formatter: Func<'TState,exn,string> -> unit
<summary> Represents a type used to perform logging. </summary>
<remarks>Aggregates most logging patterns to a single method.</remarks>
--------------------
type ILogger<'TCategoryName> = inherit ILogger
<summary> A generic interface for logging where the category name is derived from the specified <typeparamref name="TCategoryName" /> type name. Generally used to enable activation of a named <see cref="T:Microsoft.Extensions.Logging.ILogger" /> from dependency injection. </summary>
<typeparam name="TCategoryName">The type whose name is used for the logger category name.</typeparam>
type ILogger = override BeginScope<'TState> : state: 'TState -> IDisposable override IsEnabled: logLevel: LogLevel -> bool override Log<'TState> : logLevel: LogLevel * eventId: EventId * state: 'TState * ``exception`` : exn * formatter: Func<'TState,exn,string> -> unit
<summary> Represents a type used to perform logging. </summary>
<remarks>Aggregates most logging patterns to a single method.</remarks>
--------------------
type ILogger<'TCategoryName> = inherit ILogger
<summary> A generic interface for logging where the category name is derived from the specified <typeparamref name="TCategoryName" /> type name. Generally used to enable activation of a named <see cref="T:Microsoft.Extensions.Logging.ILogger" /> from dependency injection. </summary>
<typeparam name="TCategoryName">The type whose name is used for the logger category name.</typeparam>
(extension) ILoggerFactory.CreateLogger<'T>() : ILogger<'T>
(extension) ILoggerFactory.CreateLogger(``type`` : System.Type) : ILogger
ILoggerFactory.CreateLogger(categoryName: string) : ILogger
(extension) ILoggerFactory.CreateLogger(``type`` : System.Type) : ILogger
ILoggerFactory.CreateLogger(categoryName: string) : ILogger
System.IDisposable.Dispose() : unit
val key: string
val set: elements: 'T seq -> Set<'T> (requires comparison)
val v: string
IConfiguration.GetChildren() : System.Collections.Generic.IEnumerable<IConfigurationSection>
IConfiguration.GetReloadToken() : Extensions.Primitives.IChangeToken
IConfiguration.GetSection(key: string) : IConfigurationSection
FCQRS