heoo.lib 1.0.0-rc

This is a prerelease version of heoo.lib.
There is a newer version of this package available.
See the version list below for details.
dotnet add package heoo.lib --version 1.0.0-rc
NuGet\Install-Package heoo.lib -Version 1.0.0-rc
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="heoo.lib" Version="1.0.0-rc" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add heoo.lib --version 1.0.0-rc
#r "nuget: heoo.lib, 1.0.0-rc"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install heoo.lib as a Cake Addin
#addin nuget:?package=heoo.lib&version=1.0.0-rc&prerelease

// Install heoo.lib as a Cake Tool
#tool nuget:?package=heoo.lib&version=1.0.0-rc&prerelease

half-elmish-oo

This library is kind of experimental. I want to create elmish program loops (message processing loops) with a simple callback.

Example

Step1 - Design your program

open heoo.lib
open System

//Elmish programs need a model a message and update function.

type Model = { Count: int; SomeText:string }
type Message = 
    | Increase 
    | Decrease
    | Reset
    | SetText of string

let Update  (model:Model) (msg:Message) =
    match msg with
    | Increase -> { model with Count = model.Count + 1 }
    | Decrease -> { model with Count = model.Count - 1 }
    | Reset -> { model with Count = 0 }
    | SetText text -> { model with SomeText = text }
   

Step2 - Create your viewmodel

type MyVm(initialModel,messageCallback) =
    inherit ViewModelBase.T<Model,Message>(initialModel)
    
    //Remember that this is async.
    //Wait for InotifyPropertyChanged until getter is properly updated.
    member this.GetSetSomeText
        with get() =
            this.getPropertyError(
                fun m ->
                    match m.SomeText with
                    | "" -> "SomeText cannot be empty"
                    | _ -> ""
                    )//empty string is no error
            this.getPropertyValue(fun m -> m.SomeText)
        and set v = v |> SetText |> messageCallback 
    
    member this.GetCounter
        with get() = this.getPropertyValue(fun m -> m.Count)
        
    member this.IncreaseCmd = 
        CommandBase.AlwaysExecutableCommand(fun _ -> messageCallback Increase)
    member this.DecreaseCmd = 
        CommandBase.AlwaysExecutableCommand(fun _ -> messageCallback Decrease)
    member this.ResetCmd
        with get() = 
            this.getPropertyValue(fun m ->
                let canExecute = fun _ -> m.Count <> 0//already reset
                let execute = fun _ -> messageCallback Reset
                CommandBase.T(canExecute,execute)
            )
    member this.GetAllErrorMessages
        //ignore the keys (propertynames) and just get the values in an array
        with get():string array = this.getPropertyValue(
            fun model ->
                //Errors are stored as key,value pairs.
                //Where value is a function that returns a string from given model.
                this.GetErrorsArray()
                |> Array.map(fun (_,errorFunc) -> errorFunc model)
            )    

Step3 - Instantiate your program loop and viewmodel


let initialModel = { Count = 0; SomeText = "Hello World" }
let program = ElmishProgramAsync.T(initialModel,Update)
//WARNING!, once you call (IDisposable)Dispose() on the program loop, you can't use it anymore.
//like this: program.AsIDisposable().Dispose()
let viewModelInstance = MyVm(initialModel,program.PostMessage)

Step3.1 - wire OnModelUpdated to viewmodel

//Remember to wire your programs OnModelUpdated action to your viewmodel
//It might be a good idea to not write this here and move it into your gui application instead.
program.OnModelUpdated <- 
    Action<Model>(
        fun m ->
          //if this is a gui application, thread synchronization is (usually) needed.
          //This might be a good place for it to happen.
          //...
          //example: Dispatcher.Invoke(viewMModelInstance.updateModel m)
          viewModelInstance.updateModel m
    )
    |> Some

Step4 - Consume your viewmodel

Consume your viewmodel in your application (wpf, Winforms, Avalonia, MAUI.net,Uno, Unity3D etc) As you would with any other INotifyPropertyChanged, IDataErrorInfo, ICommand implementation.

Additional comments

It should be no problem to create more elmishprograms to avoid the whole monolithic approach. It's also possible to have multiple viewmodels from one program. I'm trying to leave the door open for more advanced scenarios.
Where you as a consumer is in control.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.1 263 3/1/2023
1.3.0 222 2/15/2023
1.2.5 240 2/7/2023
1.2.4 470 10/12/2022
1.2.3 433 10/6/2022
1.2.2 431 10/5/2022
1.2.1 453 9/27/2022
1.2.0 457 9/25/2022
1.1.3-rc 265 9/15/2022
1.1.2-rc 483 9/14/2022
1.1.1-rc 116 9/13/2022
1.1.0-rc 134 9/13/2022
1.0.1-rc 116 9/6/2022
1.0.0-rc 113 9/5/2022