<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Daniel Hardt .NET Developer]]></title><description><![CDATA[Thoughts and Ideas of a .NET Developer]]></description><link>https://hardt.software/</link><image><url>http://hardt.software/favicon.png</url><title>Daniel Hardt .NET Developer</title><link>https://hardt.software/</link></image><generator>Ghost 1.15</generator><lastBuildDate>Fri, 06 Mar 2026 00:04:59 GMT</lastBuildDate><atom:link href="https://hardt.software/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[How to handle external dependencies of your domain in a command-event architecture]]></title><description><![CDATA[<div class="kg-card-markdown"><h2 id="update20231219">Update: 2023-12-19</h2>
<p>I added in the code and here in this article the reader monad. To be complete about this.<br>
Also, there is a chapter &quot;The Service&quot; to explain, what is meant with the service implementation.</p>
<p>And I want to add, I mention here sometimes the phrase 'normal</p></div>]]></description><link>https://hardt.software/how-to-handle-external-dependencies-of-your-domain-in-a-command-event-architecture/</link><guid isPermaLink="false">657ddce5f8a39708583ab840</guid><category><![CDATA[fsharp]]></category><category><![CDATA[F#]]></category><category><![CDATA[domain]]></category><category><![CDATA[events]]></category><category><![CDATA[commands]]></category><category><![CDATA[event]]></category><category><![CDATA[command]]></category><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Sat, 16 Dec 2023 17:26:04 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="update20231219">Update: 2023-12-19</h2>
<p>I added in the code and here in this article the reader monad. To be complete about this.<br>
Also, there is a chapter &quot;The Service&quot; to explain, what is meant with the service implementation.</p>
<p>And I want to add, I mention here sometimes the phrase 'normal dependency injection'.<br>
As you are aware, we use in many cases things like ASP.NET Core and the build in DI container with<br>
the resulting constructor injection, I call 'normal dependency injection'.<br>
(that seem to bother also some people, that wasn't clear about the term)</p>
<p>I see this all pragmatically and foremost I describe my journey here.</p>
<p>But at least I made a reader monad implementation.</p>
<h2 id="introduction">Introduction</h2>
<p>This article will show some examples or should I say more a small journey, how to manage the dependencies in a command-event architecture.<br>
At least for me, these were the steps I took in order to solve the problem for myself.</p>
<p>To be honest all the ways I will describe here, are neither right nor wrong. (okay, the fist one feels totally wrong in F# XD)<br>
Some of them will feel weird, some of these will break some rules about purity and testability of functions.<br>
These points will be discussed also.</p>
<p>First at all I will try to establish here the example domain I use. And even example domain sound to huge for that.<br>
Please be aware, that this is NOT an article about how to model a proper domain, proper commands and events.<br>
Please shift your focus not on the domain and how we can improve it.<br>
In order to avoid the problem I will describe and focus on the dependency management itself and<br>
how we can deal with external dependencies from a programmer's perspective.</p>
<p>All the code you find here in this github repository: <a href="https://github.com/DieselMeister/blog-articles/tree/master/20231205_command_event_dependency_handling_expamples">here</a></p>
<h2 id="prerequisite">Prerequisite</h2>
<p>You should be a little aware about a command-event architecture.<br>
If you are not, please watch the videos from Greg Young about CQRS and Event Sourcing.<br>
Also read the book from Scott Wlaschin (Domain Modelling Made Functional).<br>
Also this one: <a href="https://www.youtube.com/watch?v=MHvr71T_LZw&amp;ab_channel=DCF%23Meetup">here</a></p>
<h2 id="theexample">The Example</h2>
<p>So let's begin with an example:</p>
<p>Imagine, we have an 'invoice' and when you create this invoice,<br>
there should be a customer assigned to it. Also, after we created the invoice,<br>
we want to assign some products or services the customer bought plus the quantity of it.</p>
<p>With this small domain, we want to start. And keep in mind, that we don't want to improve the domain here,<br>
we want to solve another problem.</p>
<h2 id="updatetheservice20231219">Update: The Service (2023-12-19)</h2>
<p>In the code samples you will see a service implementation.<br>
Consider it as the application layer, application service, domain service or whatever you call it.<br>
It's not important for the discussion here. But it seems, that some people get confused about it.<br>
The service is not the API-Layer like Giraffe HttpHandler or MVC Controller or something like that.<br>
And keep in mind, it's an example and not a real world application.</p>
<h2 id="thedomaindescription">The Domain Description</h2>
<p>You see here, when we create an invoice, we have to check, if the customer, even exists in our system.<br>
Also, the nature of an invoice is, that an invoice can not carry a simple reference to our customer data,<br>
you have to put in the (needed) customer data, name and address, as part of the invoice.<br>
If you change the address of your customer later in your system,<br>
your invoice is not allowed to change.<br>
Invoices are immutable (like events in event sourcing) and there are legal things you have to consider. (at least here in Germany, but I think there are similar rules in other countries)</p>
<p>The second thing, we want to do, is assigning/adding some products with some quantity and a price to the invoice.<br>
Also, here is the same rule, you can not use a reference to your products,<br>
you have to add at least the name and the price to your invoice.</p>
<p>From a UI perspective, you click on a button 'Create Invoice'<br>
and the system ask you for which customer you want to create the invoice.<br>
After that, the system provides some invoice lines, where you select a product or service and enter a quantity.</p>
<p>That's it. And yes, this 'domain' can be solved simple with a CRUD implementation, but as I said, that's not the focus here.</p>
<h2 id="theproblem">The Problem</h2>
<p>So, what's the problem here?</p>
<p>You see the invoice uses data, which is, in the most cases stored in your database in particular tables.<br>
In this case, we have here a table with customer data and a table with products/services your 'company' provides.</p>
<p>And in your domain model, you have to look into the table and check, if the data event exists,<br>
so it's valid to create an invoice for customer(id), you get from you UI. And if the customer exists,<br>
we need the data, in order to fill the invoice.</p>
<p>The same is with the products. We can send the name, price and quantity right from the UI,<br>
but in most cases we trigger the 'addition of a product' by sending a reference-id.</p>
<p>So the problem is, how to deal with the additional data we have, when do we call services or repos,<br>
in order to check and get the data.</p>
<h2 id="thedependentdatastructuresinoursystem">The (dependent) Data Structures in our System</h2>
<p>Before we start, here are some data structures, we use in our examples:</p>
<pre><code class="language-fsharp">type Product = { ProductId: string; Name: string; Price: decimal }

type Customer = { CustomerId: string; Name: string; Address: Address }
and Address = { Street: string; City: string }
</code></pre>
<p>We have a product and a customer.<br>
And we have here some Interfaces for the repositories we will use to fetch the actual data.</p>
<pre><code class="language-fsharp">type IProductRepository =
    abstract member GetProductById : string -&gt; Task&lt;Product option&gt;

type ICustomerRepository =
    abstract member GetCustomerById : string -&gt; Task&lt;Customer option&gt;
</code></pre>
<h2 id="ourdomaindatatypes">Our Domain DataTypes</h2>
<p>Our commands, we have 2 of them:</p>
<pre><code class="language-fsharp">type Command =
    | CreateInvoice of CreateInvoiceData
    | AddInvoiceLine of InvoiceLineData
    
and CreateInvoiceData = {
    InvoiceId: string
    CustomerId: string 
}

and InvoiceLineData = {
    InvoiceId: string
    ProductId: string
    Quantity: int
}
</code></pre>
<p>The Events:</p>
<pre><code class="language-fsharp">type Event =
    | InvoiceCreated of InvoiceCreatedData
    | InvoiceLineAdded of InvoiceLineAddedData
    
and InvoiceCreatedData = {
    InvoiceId: InvoiceId
    CustomerId: CustomerId
    CustomerName: CustomerName
    CustomerStreet: CustomerStreet
    CustomerCity: CustomerCity
}

and InvoiceLineAddedData = {
    InvoiceId: InvoiceId
    ProductId: ProductId
    ProductName: ProductName
    ProductPrice: ProductPrice
    ProductQuantity: ProductQuantity
    TotalPrice: TotalPrice
}
</code></pre>
<p>And the missing value types, you see in the events (they are not important):</p>
<pre><code class="language-fsharp">type InvoiceId = InvoiceId of string

type CustomerId = CustomerId of string
type CustomerName = CustomerName of string
type CustomerStreet = CustomerStreet of string
type CustomerCity = CustomerCity of string

type ProductId = ProductId of string
type ProductName = ProductName of string
type ProductPrice = ProductPrice of decimal
type ProductQuantity = ProductQuantity of int
type TotalPrice = TotalPrice of decimal
</code></pre>
<h2 id="beforewestart">Before We Start</h2>
<p>I will provide first the code, and then we talk about it.</p>
<h2 id="01theclassicoopapproach">01. The Classic OOP approach</h2>
<p>The classic OOP approach with an aggregate root and an additional aggregate.<br>
I kept it simple, no internal handling of already replayed and new events, like shown in the Greg Young example.<br>
This approach is not important when your write F#, so you can skip it, if you want.</p>
<h3 id="theboilerplate">The Boilerplate:</h3>
<pre><code class="language-fsharp">type AggregateId = AggregateId of string  

type IAggregate =
    abstract member Id : AggregateId
    
type IAggregateRoot =
    inherit IAggregate
</code></pre>
<h3 id="thedomaincode">The Domain Code:</h3>
<pre><code class="language-fsharp">type InvoiceAggregateRoot(
    id : AggregateId,
    customerRepo: ICustomerRepository,
    productRepo: IProductRepository) =
    
    // the fields
    let mutable invoiceId = InvoiceId &quot;&quot;
    let mutable customerId = CustomerId &quot;&quot;
    let mutable customerName = CustomerName &quot;&quot;
    let mutable customerStreet = CustomerStreet &quot;&quot;
    let mutable customerCity = CustomerCity &quot;&quot;
    let mutable invoiceLines: InvoiceLineAggregate list = []
    
    let mutable events: Event list = []
    
    interface IAggregateRoot with
        member _.Id = id
    
    // the properties (state)
    member _.InvoiceId        with get() = invoiceId      
    member _.CustomerId       with get() = customerId    
    member _.CustomerName     with get() = customerName  
    member _.CustomerStreet   with get() = customerStreet
    member _.CustomerCity     with get() = customerCity  
    
    member _.InvoiceLines     with get() = invoiceLines 
    
    // the event list
    member _.Events           with get() = events
    
    
    // the methods
    member this.CreateInvoice(Command.CreateInvoice cmd) =
        task {
            let! customer = customerRepo.GetCustomerById cmd.CustomerId
            match customer with
            | None -&gt; failwith &quot;invalid customer id&quot;
            | Some customer -&gt;
                let newEvent =
                    Event.InvoiceCreated {
                        InvoiceId       = InvoiceId cmd.InvoiceId
                        CustomerId      = CustomerId customer.CustomerId
                        CustomerName    = CustomerName customer.Name
                        CustomerStreet  = CustomerStreet customer.Address.Street
                        CustomerCity    = CustomerCity customer.Address.City        
                    }
                events &lt;- newEvent :: events
                this.Apply newEvent
        }
    
    
    member this.AddInvoiceLine (Command.AddInvoiceLine cmd) =
        task {
            let! product = productRepo.GetProductById cmd.ProductId
            match product with
            | None -&gt; failwith &quot;invalid product id&quot;
            | Some product -&gt;
                let newEvent =
                    Event.InvoiceLineAdded {
                        InvoiceId       = InvoiceId cmd.InvoiceId
                        ProductId       = ProductId cmd.ProductId
                        ProductName     = ProductName product.Name
                        ProductPrice    = ProductPrice product.Price
                        ProductQuantity = ProductQuantity cmd.Quantity
                        TotalPrice      = TotalPrice (product.Price * decimal cmd.Quantity)
                    }
                events &lt;- newEvent :: events
                this.Apply newEvent
        }
        
        
    member this.Apply(event) =
        match event with
        | Event.InvoiceCreated ev -&gt;
            invoiceId       &lt;- ev.InvoiceId
            customerId      &lt;- ev.CustomerId
            customerName    &lt;- ev.CustomerName
            customerStreet  &lt;- ev.CustomerStreet
            customerCity    &lt;- ev.CustomerCity
            
        | Event.InvoiceLineAdded ev -&gt;
            let invoiceLine = InvoiceLineAggregate(AggregateId &lt;| Guid.NewGuid().ToString())
            invoiceLine.Apply event
            invoiceLines &lt;- invoiceLine :: invoiceLines
            
            
    member this.ApplyEvents (events: Event list) =
        events |&gt; List.iter (fun event -&gt; this.Apply event)
    
    
and InvoiceLineAggregate(
    id : AggregateId) =
        
    // the fields
    let mutable productId = ProductId &quot;&quot;
    let mutable productName = ProductName &quot;&quot;
    let mutable productPrice = ProductPrice 0.0m
    let mutable productQuantity = ProductQuantity 0
    let mutable totalPrice = TotalPrice 0.0m
    
    interface IAggregate with
        member _.Id = id        
        
    // the properties
    member _.ProductId          with get() = productId       
    member _.ProductName        with get() = productName     
    member _.ProductPrice       with get() = productPrice    
    member _.ProductQuantity    with get() = productQuantity 
    member _.TotalPrice         with get() = totalPrice      
    
    // the methods
    
    member _.Apply (event:Event) =
        match event with
        | Event.InvoiceLineAdded event -&gt;
            productId       &lt;- event.ProductId
            productName     &lt;- event.ProductName
            productPrice    &lt;- event.ProductPrice
            productQuantity &lt;- event.ProductQuantity
            totalPrice      &lt;- event.TotalPrice
        | _ -&gt;
            failwith &quot;invalid event&quot;

</code></pre>
<h3 id="theservicecode">The Service Code:</h3>
<pre><code class="language-fsharp">    type IInvoiceRepository =
        abstract member GetInvoice : invoiceId:string -&gt; Task&lt;InvoiceAggregateRoot option&gt;
        abstract member StoreInvoice : InvoiceAggregateRoot -&gt; Task&lt;unit&gt;
    
    
    type IInvoiceService =
        abstract member CreateInvoice : invoiceId:string -&gt; customerId:string -&gt; Task&lt;unit&gt;
        abstract member AddInvoiceLine : invoiceId:string -&gt; productId:string -&gt; quantity:int -&gt; Task&lt;unit&gt;
        
     
    type IInvoiceServiceAlternative =
        abstract member ExecuteInvoiceCommand : command:Command -&gt; Task&lt;unit&gt;
    
    
    type InvoiceService(
        invoiceRepo: IInvoiceRepository,
        customerRepo: ICustomerRepository,
        productRepo: IProductRepository
        ) =
        interface IInvoiceService with
        
            member this.CreateInvoice invoiceId customerId =
                task {
                    let! invoice = invoiceRepo.GetInvoice invoiceId
                    let aggregateId = AggregateId (invoiceId)
                    let invoiceAggregate = InvoiceAggregateRoot(aggregateId, customerRepo, productRepo)
                    let command = Command.CreateInvoice { InvoiceId = invoiceId; CustomerId = customerId }
                    do! invoiceAggregate.CreateInvoice command
                    do! invoiceRepo.StoreInvoice invoiceAggregate
                }
                
                
            member this.AddInvoiceLine invoiceId productId quantity =
                task {
                    let! invoiceAggregate = invoiceRepo.GetInvoice invoiceId
                    match invoiceAggregate with
                    | None -&gt; failwith &quot;Invoice not found&quot;
                    | Some invoiceAggregate -&gt;
                        let command = Command.AddInvoiceLine { InvoiceId = invoiceId; ProductId = productId; Quantity = quantity }
                        do! invoiceAggregate.AddInvoiceLine command
                        do! invoiceRepo.StoreInvoice invoiceAggregate
                }
                
                
    type InvoiceServiceAlternative(
        invoiceRepo: IInvoiceRepository,
        customerRepo: ICustomerRepository,
        productRepo: IProductRepository
        ) =
        interface IInvoiceServiceAlternative with
        
            member this.ExecuteInvoiceCommand command =
                task {
                    let! invoice = invoiceRepo.GetInvoice command.InvoiceId
                    match command with
                    | Command.CreateInvoice cmd -&gt;
                        match invoice with
                        | None -&gt;
                            let aggregateId = AggregateId (cmd.InvoiceId)
                            let invoiceAggregate = InvoiceAggregateRoot(aggregateId, customerRepo, productRepo)
                            do! invoiceAggregate.CreateInvoice command
                            do! invoiceRepo.StoreInvoice invoiceAggregate
                        | Some _ -&gt;
                            failwith &quot;Invoice already exists&quot;
                            
                    | Command.AddInvoiceLine _ -&gt;
                        match invoice with
                        | None -&gt; failwith &quot;Invoice not found&quot;
                        | Some invoiceAggregate -&gt;
                            do! invoiceAggregate.AddInvoiceLine command
                            do! invoiceRepo.StoreInvoice invoiceAggregate
                        
                }
</code></pre>
<h3 id="thediscussion">The Discussion:</h3>
<p>Please be aware, that this is one way to implement a command-event driven domain in oop.<br>
There are probably multiple ways.<br>
It's a little based on Greg Young's 'simples-cqrs example' (<a href="https://github.com/gregoryyoung/m-r">here</a>).</p>
<p>So let's discuss this approach from the perspective of handling the dependencies and the<br>
additional data we need from the database in order to fill the events and out final state:</p>
<p>The 'classic OOP' has the 'advantage' that, it's pretty forward in handling the dependencies.<br>
It uses classic dependency injection and injects the necessary repository interfaces into the constructor of the aggregate root itself.<br>
The methods 'CreateInvoice' and 'AddInvoiceLine' in the domain code call the repositories to get the data and<br>
if they don't get them, they throw an exception.<br>
(I know and hope, this time around, the people will also work with results in C#, this example above is not idiomatic F# at all)</p>
<p>That's a pretty forward implementation. It's easy to achieve, beside the huge boilerplate code,<br>
but if you implement that in C# it's a common approach.<br>
(We will in the next approach, how we 'optimize' that approach and make it more 'functional')</p>
<h4 id="whatabouttesting">What about testing?</h4>
<p>You have to Mock all interfaces, you use.<br>
That is in OOP a total normal approach.<br>
But it's tedious to mock.<br>
Also, it's also not a pure implementation of the domain, which can cause issues down the line.</p>
<h4 id="conclusion">Conclusion</h4>
<p>It's not something I would ever implement in F#.<br>
Also not in C# anymore, because I know better now.<br>
I didn't like the whole encapsulation stuff and these Aggregate-Root and sub Aggregate stuff. So for me personal a no.<br>
In my opinion the whole stuff came up, when someone in the OOP world said, that 'anemic domain model' are an anti-pattern.<br>
Nevertheless, it's a valid approach for people who like it.<br>
It's not wrong. I harder to test, maybe harder to understand and the injection of the interfaces can cause issues,<br>
but it's easy and straight forward.</p>
<h2 id="02themorefidiomaticway">02. The More F# Idiomatic Way</h2>
<p>So, let's see, how we can do that in a more F# idiomatic way.</p>
<h3 id="thestate">The State:</h3>
<pre><code class="language-fsharp">type InvoiceState = {
    InvoiceId      : InvoiceId 
    CustomerId     : CustomerId
    CustomerName   : CustomerName
    CustomerStreet : CustomerStreet
    CustomerCity   : CustomerCity
    
    InvoiceLines   : InvoiceLine list
}
and InvoiceLine = {
    ProductId        : ProductId
    ProductName      : ProductName
    ProductPrice     : ProductPrice
    ProductQuantity  : ProductQuantity
    TotalPrice       : TotalPrice
}
</code></pre>
<h3 id="thedomaincode">The Domain Code:</h3>
<pre><code class="language-fsharp">// execute a command (decider)
let execute getCustomer getProduct command state =
    task {
        match state, command with
        | None, Command.CreateInvoice cmd -&gt;
            let! (customer:DataTypes.Customer option) = getCustomer cmd.CustomerId
            match customer with
            | None -&gt;
                return Error $&quot;customer '{cmd.CustomerId}' does not exist&quot;
            | Some customer -&gt;
                return [
                    Event.InvoiceCreated {
                        InvoiceId      = InvoiceId cmd.InvoiceId
                        CustomerId     = CustomerId cmd.CustomerId
                        CustomerName   = CustomerName customer.Name
                        CustomerStreet = CustomerStreet customer.Address.Street
                        CustomerCity   = CustomerCity customer.Address.City
                    }
                ] |&gt; Ok
            
        | Some state, Command.AddInvoiceLine cmd -&gt;
            let! (product:DataTypes.Product option) = getProduct cmd.ProductId
            match product with
            | None -&gt;
                return Error $&quot;product '{cmd.ProductId}' does not exist&quot;
            | Some product -&gt;
                return [
                    Event.InvoiceLineAdded {
                        InvoiceId        = state.InvoiceId
                        ProductId        = ProductId cmd.ProductId
                        ProductName      = ProductName product.Name
                        ProductPrice     = ProductPrice product.Price
                        ProductQuantity  = ProductQuantity cmd.Quantity
                        TotalPrice       = TotalPrice (product.Price * decimal cmd.Quantity)
                    }
                ] |&gt; Ok
            
        | Some state, Command.CreateInvoice _ -&gt;
            return Error &quot;invoice already exists&quot;
        | None, Command.AddInvoiceLine _ -&gt;
            return Error &quot;invoice does not exist&quot;
    }
    
    
// apply an event (state transition)
let apply event state =
    match event, state with
    | Event.InvoiceCreated ev, None -&gt;
        Some {
            InvoiceId      = ev.InvoiceId
            CustomerId     = ev.CustomerId
            CustomerName   = ev.CustomerName
            CustomerStreet = ev.CustomerStreet
            CustomerCity   = ev.CustomerCity
            InvoiceLines   = []
        }
    | Event.InvoiceLineAdded ev, Some state -&gt;
        Some {
            state with
                InvoiceLines = {
                    ProductId        = ev.ProductId
                    ProductName      = ev.ProductName
                    ProductPrice     = ev.ProductPrice
                    ProductQuantity  = ev.ProductQuantity
                    TotalPrice       = ev.TotalPrice
                } :: state.InvoiceLines
        }
    | _, _ -&gt;
        None
        
        
let applyEvents events state =
    (events, state)
    ||&gt; List.fold (fun state event -&gt; apply event state)
</code></pre>
<h3 id="theservicecode">The Service Code:</h3>
<pre><code class="language-fsharp">// somewhere we have our invoice repository, but here with a slightly different singature
type IInvoiceRepository =
    abstract member GetInvoice : invoiceId:string -&gt; Task&lt;InvoiceState option&gt;
    abstract member StoreInvoice : InvoiceState -&gt; Task&lt;unit&gt;

// i am using here my personal preferred way to have one execute function also in the service
type IInvoiceService =
    abstract member ExecuteInvoiceCommand : command:Command -&gt; Task&lt;unit&gt;



let private executeCommand
    (invoiceRepo:IInvoiceRepository)
    (customerRepo:ICustomerRepository)
    (productRepo:IProductRepository)
    (command:Command) =
    task {
        // partial application of the execute function
        let executeCommand = execute customerRepo.GetCustomerById productRepo.GetProductById
        let! invoice = invoiceRepo.GetInvoice command.InvoiceId
        let! result = invoice |&gt; executeCommand command
        match result with
        | Error e -&gt; failwith e
        | Ok events -&gt;
            let newInvoiceState = applyEvents invoice events
            match newInvoiceState with
            | None -&gt; failwith &quot;no state returned after events applied&quot;
            | Some newInvoiceState -&gt;
                do! invoiceRepo.StoreInvoice newInvoiceState
    }
    
    
    
let createInvoiceService (invoiceRepo:IInvoiceRepository) (customerRepo:ICustomerRepository) (productRepo:IProductRepository) =
    { new IInvoiceService with
        member this.ExecuteInvoiceCommand command =
            executeCommand invoiceRepo customerRepo productRepo command
    }
    
// or as an alternative
type InvoiceService(
    invoiceRepo:IInvoiceRepository,
    customerRepo:ICustomerRepository,
    productRepo:IProductRepository) =
    interface IInvoiceService with
        member this.ExecuteInvoiceCommand command =
            executeCommand invoiceRepo customerRepo productRepo command
</code></pre>
<h3 id="thediscussion">The Discussion:</h3>
<p>The first thing you see is, that we are not using any aggregate root or sub aggregates.<br>
We are using a simple state, which is a record type.<br>
You can argue about that and the whole aggregate id and not structural equality stuff, but that's not the focus here.</p>
<p>The domain code is pretty simple.<br>
You have an 'execute' function, which decides, if a command is valid or not. It returns a list of events or an error.<br>
We have an 'apply' function, which applies an event to a state and returns a new state.<br>
And we have an 'applyEvents' function, which applies a list of events to a state and returns a new state.<br>
In our further discussion, the 'apply' and 'applyEvents' function will not change any more, so I will leave them out of the code.</p>
<p>Let's focus on the 'execute' function. In order to generate the necessary events, we need, like in the OOP approach,<br>
additional data from the database. Our customer and out product.<br>
In this approach we inject the necessary functions to get the data from the database into the 'execute' function.</p>
<p>Later in the service code, we partially apply these functions with the help of your repository interfaces.</p>
<p>Did this approach help us with the dependency management? No. If you think about this approach, this approach tends to<br>
get fast out of hands by using more and more parameters in the 'execute' function.<br>
In the OOP approach these parameters inside the constructor feels more natural and<br>
the execution methods do not have that many parameters.</p>
<h4 id="whatabouttesting">What about testing?</h4>
<p>So instead of mocking interfaces, we have to mock functions and injecting them into the 'execute' function. That doesn't feel better at all.</p>
<h4 id="conclusion">Conclusion</h4>
<p>The idiomatic F# approach feels more comfortable and in it's core more elegant, then the OOP approach.<br>
We using the functional way to separate data and functions. But we get this parameter problem, which gets out of hands pretty fast.<br>
Also the execute function is not pure. We are using a task an call the repositories inside the execute function.</p>
<p>How we handle the problem with parameters, we will see in the next chapter. For the other problem, we have to wait.</p>
<h2 id="03tryhidingthedependenciesmarki">03. Try Hiding The Dependencies (Mark I)</h2>
<p>So, let's see, how we can hide the dependencies in the execute function in order to get rid of the parameter problem. At least partially.</p>
<h3 id="thedomaincode">The Domain Code:</h3>
<pre><code class="language-fsharp">type Dependencies = {
        GetCustomer : string -&gt; Task&lt;DataTypes.Customer option&gt;
        GetProduct  : string -&gt; Task&lt;DataTypes.Product option&gt;
    }

// execute a command (decider)
let execute dependencies command state =
    task {
        match state, command with
        | None, Command.CreateInvoice cmd -&gt;
            let! (customer:DataTypes.Customer option) = dependencies.GetCustomer cmd.CustomerId
            match customer with
            | None -&gt;
                return Error $&quot;customer '{cmd.CustomerId}' does not exist&quot;
            | Some customer -&gt;
                return [
                    Event.InvoiceCreated {
                        InvoiceId      = InvoiceId cmd.InvoiceId
                        CustomerId     = CustomerId cmd.CustomerId
                        CustomerName   = CustomerName customer.Name
                        CustomerStreet = CustomerStreet customer.Address.Street
                        CustomerCity   = CustomerCity customer.Address.City
                    }
                ] |&gt; Ok
            
        | Some state, Command.AddInvoiceLine cmd -&gt;
            let! (product:DataTypes.Product option) = dependencies.GetProduct cmd.ProductId
            match product with
            | None -&gt;
                return Error $&quot;product '{cmd.ProductId}' does not exist&quot;
            | Some product -&gt;
                return [
                    Event.InvoiceLineAdded {
                        InvoiceId        = state.InvoiceId
                        ProductId        = ProductId cmd.ProductId
                        ProductName      = ProductName product.Name
                        ProductPrice     = ProductPrice product.Price
                        ProductQuantity  = ProductQuantity cmd.Quantity
                        TotalPrice       = TotalPrice (product.Price * decimal cmd.Quantity)
                    }
                ] |&gt; Ok
            
        | Some state, Command.CreateInvoice _ -&gt;
            return Error &quot;invoice already exists&quot;
        | None, Command.AddInvoiceLine _ -&gt;
            return Error &quot;invoice does not exist&quot;
    }
</code></pre>
<h3 id="theservicecode">The Service Code:</h3>
<pre><code class="language-fsharp">let private executeCommand
    (invoiceRepo:IInvoiceRepository)
    (dependencies:Dependencies)
    (command:Command) =
    task {
        // partial application of the execute function
        let executeCommand = execute dependencies
        let! invoice = invoiceRepo.GetInvoice command.InvoiceId
        let! result = invoice |&gt; executeCommand command
        match result with
        | Error e -&gt; failwith e
        | Ok events -&gt;
            let newInvoiceState = applyEvents invoice events
            match newInvoiceState with
            | None -&gt; failwith &quot;no state returned after events applied&quot;
            | Some newInvoiceState -&gt;
                do! invoiceRepo.StoreInvoice newInvoiceState
    }
    
    // ...
    
</code></pre>
<h3 id="thediscussion">The Discussion:</h3>
<p>What we here did is to collect all the parameters to one record we call 'Dependencies'. Yes, I know, that sounds creative, I know.<br>
Also there is nothing much to discuss. At least we reduced the dependencies to one parameter.<br>
The Dependency record will grow fast and it has to be initialized fully before we can use it.</p>
<h4 id="whatabouttesting">What about testing?</h4>
<p>Nothing changed in this approach.</p>
<h4 id="conclusion">Conclusion</h4>
<p>We didn't solve the problem, we just moved it to another place. But at least our code doesn't look too bad on the domain level. Now it's elsewhere in our code.</p>
<h2 id="04morefunctionalpurityandtestability">04. More Functional Purity and Testability</h2>
<p>Okay, now that our execute function only takes 3 parameters and we can focus on testability.<br>
A wonderful approach to get better testability is to make our domain a pure function.<br>
With that we get always the same result for the same input.</p>
<h3 id="thedomaincode">The Domain Code:</h3>
<pre><code class="language-fsharp">type Dependencies = {
        NeededCustomerForCreateInvoice : DataTypes.Customer option
        NeededProductForAddInvoiceLine : DataTypes.Product option
    } with
        static member Empty = {
            NeededCustomerForCreateInvoice = None
            NeededProductForAddInvoiceLine  = None
        }

// execute a command (decider)
let execute dependencies command state =
    match state, command with
    | None, Command.CreateInvoice cmd -&gt;
        match dependencies.NeededCustomerForCreateInvoice with
        | None -&gt;
            Error $&quot;customer '{cmd.CustomerId}' does not exist&quot;
        | Some customer -&gt;
            [
                Event.InvoiceCreated {
                    InvoiceId      = InvoiceId cmd.InvoiceId
                    CustomerId     = CustomerId cmd.CustomerId
                    CustomerName   = CustomerName customer.Name
                    CustomerStreet = CustomerStreet customer.Address.Street
                    CustomerCity   = CustomerCity customer.Address.City
                }
            ] |&gt; Ok
        
    | Some state, Command.AddInvoiceLine cmd -&gt;
        match dependencies.NeededProductForAddInvoiceLine with
        | None -&gt;
            Error $&quot;product '{cmd.ProductId}' does not exist&quot;
        | Some product -&gt;
            [
                Event.InvoiceLineAdded {
                    InvoiceId        = state.InvoiceId
                    ProductId        = ProductId cmd.ProductId
                    ProductName      = ProductName product.Name
                    ProductPrice     = ProductPrice product.Price
                    ProductQuantity  = ProductQuantity cmd.Quantity
                    TotalPrice       = TotalPrice (product.Price * decimal cmd.Quantity)
                }
            ] |&gt; Ok
        
    | Some state, Command.CreateInvoice _ -&gt;
        Error &quot;invoice already exists&quot;
    | None, Command.AddInvoiceLine _ -&gt;
        Error &quot;invoice does not exist&quot;
</code></pre>
<h3 id="theservicecode">The Service Code:</h3>
<pre><code class="language-fsharp">let private executeCommand
    (invoiceRepo:IInvoiceRepository)
    (customerRepo:ICustomerRepository)
    (productRepo:IProductRepository)
    (command:Command) =
    task {
        
        let! invoice = invoiceRepo.GetInvoice command.InvoiceId
        
        // build the dependencies record based on the incoming commands
        let! dependencies =
            task {
                match command with
                | Command.CreateInvoice cmd -&gt;
                    let! customer = customerRepo.GetCustomerById cmd.CustomerId
                    return { Dependencies.Empty with NeededCustomerForCreateInvoice = customer }
                | Command.AddInvoiceLine cmd -&gt;
                    let! product = productRepo.GetProductById cmd.ProductId
                    return { Dependencies.Empty with NeededProductForAddInvoiceLine = product }
            }
        
        // this one it pure and perfectly testable    
        let result = invoice |&gt; execute dependencies command
        
        match result with
        | Error e -&gt; failwith e
        | Ok events -&gt;
            let newInvoiceState = applyEvents invoice events
            match newInvoiceState with
            | None -&gt; failwith &quot;no state returned after events applied&quot;
            | Some newInvoiceState -&gt;
                do! invoiceRepo.StoreInvoice newInvoiceState
    }
    
    

type InvoiceService(
    invoiceRepo:IInvoiceRepository,
    customerRepo:ICustomerRepository,
    productRepo:IProductRepository) =
    interface IInvoiceService with
        member this.ExecuteInvoiceCommand command =
            executeCommand invoiceRepo customerRepo productRepo command
</code></pre>
<h3 id="thediscussion">The Discussion:</h3>
<p>In order to get our 'execute' function pure, we removed all the external calls from the code and the 'dependencies' record.<br>
It's also not a task computation anymore.<br>
What we have here now, is the pure data inside the dependency record we need to execute the command.<br>
With that the whole 'execute' function become pure and better testable.<br>
We build our repositories, that they return option types, so we can easily left the check, if a customer or product exists,<br>
like it already was. If it's none, then it's not there. Easy enough.</p>
<p>With that, we moved the external calls to the database up to the service implementation.<br>
It's now a 'impure-pure-impure' sandwich on the service level.</p>
<p>You see there, that the dependencies are build based on the command, which came in. This is an impure part.<br>
After that, we call the 'pure' execute function and get the result and after that,<br>
we call the database to store our new state. This one is again 'impure'.</p>
<p>What's with the apply function? That's a good question. Because we throw in our example exceptions there,<br>
the apply function is considered impure. I leave you to decide, which approach you want. The function can easily be made pure.<br>
But keep in mind, that a missing application of an event to a state is, for me at least, considered an exceptional error in your system.<br>
It shouldn't happen, if it is happening, your code is wrong and you have to fix it.<br>
My personal opinion about that is to throw an exception.</p>
<p>Btw. the code of the 'apply' you see in the chapter '02. The More F# Idiomatic Way'. I left it out, because it's the same in part 2 to 5.</p>
<p>One thing, the dependency record can grow bigger and bigger and you will have problem, which property is for what command.<br>
And that can became a problem. Use proper names in order to know which one blogs to which one.</p>
<h4 id="whatabouttesting">What about testing?</h4>
<p>Now that we have a pure function, we are basically in the testing heaven. Same input generates the same output. What do we want more?<br>
We have to write test data nevertheless or use property based testing to generate the data for us. (I never tried property testing at all.)</p>
<h4 id="conclusion">Conclusion</h4>
<p>We are almost at the end of our journey. We have now a pure function and only one additional parameter in our execute function.</p>
<p>But for me, we only moved the our problem one level up. And I am not satisfied with that. Because our dependency record can grow and grow<br>
and for every additional data we need, wee need to add a property there. And that maybe become confusing over time.<br>
Even if you use proper names for the properties. It feels like, that the dependency record should not be responsible for all the needed dependencies of you domain.</p>
<p>For small domains, with not that much additional data, it's totally fine in my option. But can we do better?</p>
<h2 id="05tryhidingthedependenciesmarkii">05. Try Hiding The Dependencies (Mark II)</h2>
<p>So that's the last approach we discuss here for now. Here we want to solve the problem,<br>
that we have basically one dependency record for all the commands in our domain.<br>
And somehow every command should manage there own needed dependencies.</p>
<p>And that's what we will do here and not break the purity of our execute function.</p>
<h3 id="thedomaincode">The Domain Code:</h3>
<pre><code class="language-fsharp">// we putting our dependencies into our command, for that we add some &quot;internal&quot; commands
// we distinguish between commands which came through our api and command which we are using internally

// our external commands
[&lt;RequireQualifiedAccess&gt;]
type ExternalCommand =
    | CreateInvoice of ExternalCreateInvoiceData
    | AddInvoiceLine of ExternalInvoiceLineData
        
        member this.InvoiceId =
            match this with
            | CreateInvoice data -&gt; data.InvoiceId
            | AddInvoiceLine data -&gt; data.InvoiceId
    
and ExternalCreateInvoiceData = {
    InvoiceId: string
    CustomerId: string 
}

and ExternalInvoiceLineData = {
    InvoiceId: string
    ProductId: string
    Quantity: int
}


// our internal commands
[&lt;RequireQualifiedAccess&gt;]
type Command =
    | CreateInvoice of CreateInvoiceData
    | AddInvoiceLine of InvoiceLineData
        
        member this.InvoiceId =
            match this with
            | CreateInvoice data -&gt; data.InvoiceId
            | AddInvoiceLine data -&gt; data.InvoiceId
    
and CreateInvoiceData = {
    InvoiceId: string
    CustomerId: string
    Customer: Customer option
}

and InvoiceLineData = {
    InvoiceId: string
    ProductId: string
    Quantity: int
    Product: Product option
}
</code></pre>
<h3 id="theservicecode">The Service Code:</h3>
<pre><code class="language-fsharp">// btw for the repository dependencies here, you can also use a dependency record. Or move this directly into the service class
let private executeCommand
    (invoiceRepo:IInvoiceRepository)
    (customerRepo:ICustomerRepository)
    (productRepo:IProductRepository)
    (command:ExternalCommand) =
    task {
        
        let! invoice = invoiceRepo.GetInvoice command.InvoiceId
        
        // build the internal commands
        let! internalCommand =
            task {
                match command with
                | ExternalCommand.CreateInvoice cmd -&gt;
                    let! customer = customerRepo.GetCustomerById cmd.CustomerId
                    return Command.CreateInvoice {
                        InvoiceId = cmd.InvoiceId
                        CustomerId = cmd.CustomerId
                        Customer = customer
                    }
                | ExternalCommand.AddInvoiceLine cmd -&gt;
                    let! product = productRepo.GetProductById cmd.ProductId
                    return Command.AddInvoiceLine {
                        InvoiceId = cmd.InvoiceId
                        ProductId = cmd.ProductId
                        Product = product
                        Quantity = cmd.Quantity
                    }
            }
        
        let result = invoice |&gt; execute internalCommand
        
        match result with
        | Error e -&gt; failwith e
        | Ok events -&gt;
            let newInvoiceState = applyEvents invoice events
            match newInvoiceState with
            | None -&gt; failwith &quot;no state returned after events applied&quot;
            | Some newInvoiceState -&gt;
                do! invoiceRepo.StoreInvoice newInvoiceState
    }
    
    

type InvoiceService(
    invoiceRepo:IInvoiceRepository,
    customerRepo:ICustomerRepository,
    productRepo:IProductRepository) =
    interface IInvoiceService with
        member this.ExecuteInvoiceCommand command =
            executeCommand invoiceRepo customerRepo productRepo command
</code></pre>
<h3 id="thediscussion">The Discussion:</h3>
<p>What we here did is introduce the concept on an internal and external command.<br>
The external commands, are the commands, you use in your api.<br>
The internal commands have additional properties in their payload, which are relevant for the execution of the command.</p>
<p>That sound tedious, because now you have to maintain two command types. But the advantage you get, is that you have<br>
the dependencies inside the command itself, so you didn't have to maintain the dependency record from the previous chapter.</p>
<p>I mentioned in the previous chapter that the dependency record approach is fine when you have a small amount of additional data.</p>
<p>But if when you get more, it makes sense to move the dependencies to the command itself and have clear 'responsibilities'.</p>
<p>And let's be honest, copy-pasting the commands you already have and extend them is not that much work.</p>
<p>Also some of you maybe already have dto's in you api, and do not use the commands we have here at all.<br>
In that case, you have only one set of commands with the necessary dependencies and do the 'mapping' already on the service level.</p>
<h4 id="whatabouttesting">What about testing?</h4>
<p>We are already in testability heaven and that didn't change here.</p>
<h4 id="conclusion">Conclusion</h4>
<p>As I mentioned, that's the approach I personally prefer.<br>
It's a little more work (maybe), but it's more clear and you have a better separation of concerns.</p>
<p>And least for me, I am satisfied with this solution and it solves perfectly my problem to manage the dependencies and additional data I need in my domains.</p>
<h2 id="thepreviousversionthereadermonad">The Previous Version: The Reader Monad</h2>
<p>Yes, I know, I know. I didn't mention the reader monad at all. You see in the examples, that I use on service level<br>
the classic oop dependency injection approach, because in practical terms I will use for these services asp.net core and for example giraffe or Azure Functions.<br>
And the build in dependency injection container works fine and we didn't have to make it more complicated.</p>
<p>Also I didn't work out any solution with a reader monad. I invite you, I am curios, how you would exactly this example with a reader monad.<br>
And which advantage you can in readability and testability.</p>
<p>I personally do not like to much 'magic*' in the code, where things are suddenly hidden. Someone has to maintain it.<br>
But that's my personal opinion.</p>
<p>*I mean writing code with F# feels like magic, if you compare it to C# or Java.</p>
<p>BUT I really like to see a solution with a reader monad. So if you have one, please let me know.<br>
(I found someone :D)</p>
<h2 id="updated06thereadermonad">Updated: 06. The Reader Monad</h2>
<p>With the help of two articles, one from Bartosz Sypytkowski (<a href="https://www.bartoszsypytkowski.com/dealing-with-complex-dependency-injection-in-f/">here</a>) and one from Scott Wlaschin (<a href="https://fsharpforfunandprofit.com/posts/dependencies-3/">here</a>)<br>
I made an implementation of a reader monad on the service level.<br>
The domain code itself is pure and the reader monad didn't change there anything.</p>
<h3 id="thereadermonadimplementationcalledheredependencycallitwhateveryouwant">The Reader Monad Implementation (called here Dependency - call it whatever you want)</h3>
<pre><code class="language-fsharp">[&lt;Struct&gt;] type Dependency&lt;'env, 'out&gt; = Dependency of ('env -&gt; 'out)
module Dependency =
    /// Create value with no dependency requirements.
    let inline value (x: 'out): Dependency&lt;'env,'out&gt; = Dependency (fun _ -&gt; x)
    /// Create value which uses dependency.
    let inline apply (fn: 'env -&gt; 'out): Dependency&lt;'env,'out&gt; = Dependency fn
    
    let run (env: 'env) (Dependency fn): 'out = fn env
    
    let inline bind (fn: 'a -&gt; Dependency&lt;'env,'b&gt;) effect =
        Dependency (fun env -&gt;
            let x = run env effect // compute result of the first effect
            run env (fn x) // run second effect, based on result of first one
        )
        
    let inline get&lt;'a&gt; = Dependency id
        
[&lt;Struct&gt;]
type DependencyBuilder =
    member inline __.Return value = Dependency.value value
    member inline __.Zero () = Dependency.value (Unchecked.defaultof&lt;_&gt;)
    member inline __.ReturnFrom (effect: Dependency&lt;'env, 'out&gt;) = effect
    member inline __.Bind(effect, fn) = Dependency.bind fn effect
    
let dependency = DependencyBuilder()
</code></pre>
<h3 id="anewinterface">A New Interface</h3>
<pre><code class="language-fsharp">type IDependencies =
    inherit IInvoiceRepository
    inherit ICustomerRepository
    inherit IProductRepository
</code></pre>
<h3 id="theservicecode">The Service Code:</h3>
<pre><code class="language-fsharp">// here we use instead of normal parameter injection, a reader monad (called dependency here)
let private executeCommand (command:ExternalCommand) =
    dependency {
        let! (env:IDependencies) = Dependency.get
        
        return task {
            let! invoice = env.GetInvoice command.InvoiceId
            // build the internal commands
            let! internalCommand =
                task {
                    match command with
                    | ExternalCommand.CreateInvoice cmd -&gt;
                        let! customer = env.GetCustomerById cmd.CustomerId
                        return Command.CreateInvoice {
                            InvoiceId = cmd.InvoiceId
                            CustomerId = cmd.CustomerId
                            Customer = customer
                        }
                    | ExternalCommand.AddInvoiceLine cmd -&gt;
                        let! product = env.GetProductById cmd.ProductId
                        return Command.AddInvoiceLine {
                            InvoiceId = cmd.InvoiceId
                            ProductId = cmd.ProductId
                            Product = product
                            Quantity = cmd.Quantity
                        }
                }
            
            let result = invoice |&gt; execute internalCommand
            
            match result with
            | Error e -&gt; failwith e
            | Ok events -&gt;
                let newInvoiceState = applyEvents invoice events
                match newInvoiceState with
                | None -&gt; failwith &quot;no state returned after events applied&quot;
                | Some newInvoiceState -&gt;
                    do! env.StoreInvoice newInvoiceState
        }    
    }
    
    
    
type InvoiceService(dependencies:IDependencies) =
    interface IInvoiceService with
        member this.ExecuteInvoiceCommand command =
            Dependency.run dependencies (executeCommand command)
</code></pre>
<h3 id="thediscussion">The Discussion:</h3>
<p>Okay, I read some blog posts and tried to understand the reader monad.<br>
(it seems to offend people, not to use one!)</p>
<p>So the implementation of the reader monad you see everywhere an I will not describe them.<br>
But I encourage you to read the blog posts I mentioned above.</p>
<p>In the end you have a computation expression (here called 'dependency'),<br>
which you can use to 'inject' your dependencies into your code.</p>
<p>A base thing here is that we unify all our dependencies into one interface.<br>
And then hide the 'injection' with the help of the reader monad.</p>
<p>The cool thing here is, that I can call functions inside the reader monad,<br>
which are also reader monads and so one, but for this simple example,<br>
we only hide this one dependency interface.</p>
<p>I definitely have to got deeper in it and see the advantage of it.</p>
<h4 id="whatabouttesting">What about testing?</h4>
<p>same as before. We have a pure function and we can test it easily.</p>
<h4 id="conclusion">Conclusion</h4>
<p>The reader monad is a cool thing. I changes how I inject the things.</p>
<p>And now came the BUT for this example and an implementation for a 'command executor'.</p>
<p>I can also inject this single interface as an additional parameter.</p>
<pre><code class="language-fsharp">let private executeCommand
    (env:IDependencies)
    (command:ExternalCommand) =
    //...
</code></pre>
<p>(In the code you see it as the file 07)</p>
<p>Here you see, I did it! I injected the dependencies as an additional parameter.</p>
<p>Because I have here only this one function, which is not a composition of multiple functions with multiple dependencies.<br>
And for this particular example, I don't see the advantage of the reader monad.</p>
<p>And again BUT: If the application grows and you have more and more dependencies,<br>
then the reader monad is a cool thing to hide the dependencies and make the code more readable.<br>
In the end you need only once some 'boilerplate' to have the code for the monad and then you can use it everywhere.</p>
<p>Also a reader monad makes you code not magically pure. If you inject async operations, then you are not pure at all.</p>
<h2 id="lastwordyourhonord">Last word (your honor) :D</h2>
<p>I hope you liked this little journey through the different approaches to handle dependencies in your domain.<br>
For me I have found my personal favorite approach to handle additional data in my domain.</p>
<p>I am curios, what did you do in order to handle this problem. Please let me know.</p>
<h3 id="merrychristmasandahappynewyeartoallofyouyouareanawesomecommunity">Merry Christmas and a happy new year to all of you. You are an awesome community!</h3>
<p>Twitter: @HardtITSolution<br>
The Code: <a href="https://github.com/hardt-coded/blog-articles/tree/master/20231205_command_event_dependency_handling_expamples">here</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Convert old .vstheme file from Visual Studio 2019 to Visual Studio 2022 (VSIX-Theme)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Hi. Today I tried the new version of Visual Studio and I immediately realized, that the old &quot;Visual Studio Color Theme Editor&quot; is not available. So how do I get my hard changed theme to VS 2022? This post will show you how you can convert your old</p></div>]]></description><link>https://hardt.software/convert-old-vstheme-file-from-vs-2019-to-vs-2022/</link><guid isPermaLink="false">6171d38cde6e566b78e001c0</guid><category><![CDATA[Theme]]></category><category><![CDATA[Visual Studio]]></category><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Thu, 21 Oct 2021 21:22:50 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Hi. Today I tried the new version of Visual Studio and I immediately realized, that the old &quot;Visual Studio Color Theme Editor&quot; is not available. So how do I get my hard changed theme to VS 2022? This post will show you how you can convert your old .vstheme file to a new VSIX-Theme-Extension.</p>
<ol>
<li>
<p>You need the then nuget package &quot;Microsoft.VisualStudio.VsixColorCompiler&quot;. This nuget contains the VSixColorCompiler.exe which converts your .vstheme file to a .pkgdef file. With this file, we will build the VSIX to import your Theme into VS 2022.</p>
<ul>
<li>
<p>create a new console or class project in VS 2022</p>
</li>
<li>
<p>Install the nuget package &quot;Microsoft.VisualStudio.VsixColorCompiler&quot; into this project.<br>
<a href="https://www.nuget.org/packages/Microsoft.VisualStudio.VsixColorCompiler/">https://www.nuget.org/packages/Microsoft.VisualStudio.VsixColorCompiler/</a></p>
</li>
<li>
<p>now open a command line console or the VS Terminal (View &gt; Terminal)</p>
</li>
<li>
<p>open the folder for the installed nuget package. You find it here: &quot;C:\Users[Your Username].nuget\packages\17.0.31709.430\VsixColorCompiler.exe&quot; (the version number can maybe differ, if is a new version of the nuget package released in the future.</p>
</li>
<li>
<p>run following command:</p>
</li>
</ul>
<pre><code>VsixColorCompiler.exe [here your .vstheme file] [here the target folder and name of the oputput with.pkgdef]

// example
VsixColorCompiler.exe C:\somewhere\myTheme.vstheme c:\whatever\myTheme.pkgdef
</code></pre>
</li>
</ol>
<ul>
<li>this part is done, we have out pkgdef file!</li>
</ul>
<ol start="2">
<li>
<p>Now we need to create a VSIX Project inside VS 2022. (Don't forget to install the Extension Workflow, to get the Project)</p>
<ul>
<li>
<p>Create an Empty VSIX Project Inside Visual Studio<br>
<img src="https://hardt.software/content/images/2021/10/01_ScreenShot_vstheme_2022_VSIX_Project.png" alt="01_ScreenShot_vstheme_2022_VSIX_Project"></p>
</li>
<li>
<p>use Add Existing Item to add you generated &quot;.pkgdef&quot; file to the project<br>
<img src="https://hardt.software/content/images/2021/10/02_ScreenShot_vstheme_add_Existing_file.png" alt="02_ScreenShot_vstheme_add_Existing_file"></p>
</li>
<li>
<p>change the file property setting as in this image:<br>
<img src="https://hardt.software/content/images/2021/10/03_ScreenShot_vstheme_file_props.png" alt="03_ScreenShot_vstheme_file_props"></p>
</li>
<li>
<p>optional: edit the manifest file in order to get a nice name for your extension! ;)</p>
</li>
<li>
<p>build the project!</p>
</li>
<li>
<p>go to the output directory and run the created VSIX-File.</p>
</li>
</ul>
</li>
</ol>
<p>Done!</p>
<p>I hope this helps you.</p>
<p>Daniel</p>
</div>]]></content:encoded></item><item><title><![CDATA[(Video Tutorial) F# - How to build a realtime themometer with F#, the SAFE-Stack and a RaspberryPi (GrovePi)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Welcome to a new (short) tutorial about: &quot;How to build a realtime thermometer with F#, the SAFE Stack and a RaspberryPi (GrovePi)&quot;</p>
<iframe width="1000" height="563" src="https://www.youtube-nocookie.com/embed/iLfzESKpD4Q?list=PLZdZgL_WoFtmtTtdFoEx7zBqBeYASv2mF" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>In this tutorial we will cover 4 things.</p>
<ul>
<li>
<p>build a simple data stream for the temperature data in saturn</p>
<ul>
<li>first with some random data, and as</li></ul></li></ul></div>]]></description><link>https://hardt.software/video-tutorial/</link><guid isPermaLink="false">5f39ae1f814a403f00fd502f</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Sun, 16 Aug 2020 22:09:44 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Welcome to a new (short) tutorial about: &quot;How to build a realtime thermometer with F#, the SAFE Stack and a RaspberryPi (GrovePi)&quot;</p>
<iframe width="1000" height="563" src="https://www.youtube-nocookie.com/embed/iLfzESKpD4Q?list=PLZdZgL_WoFtmtTtdFoEx7zBqBeYASv2mF" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>In this tutorial we will cover 4 things.</p>
<ul>
<li>
<p>build a simple data stream for the temperature data in saturn</p>
<ul>
<li>first with some random data, and as last step with the real data from my GrovePi</li>
</ul>
</li>
<li>
<p>use saturn channels to build a web socket connection which sends the data to the web clients</p>
</li>
<li>
<p>use emlish to consume the web sockets messages and display the temperature and humidity</p>
</li>
<li>
<p>build an elmish wrapper around a react component, to display the data in a fancy way.</p>
</li>
</ul>
<p>I have to admit, it's the software part, not the hardware. The hardware was actually plugin the DHT-Sensor into the GrovePi Board. So Sorry if someone hoped for the hardware part.</p>
<p>Special Thanks to Zaid Ajaj, woh creates awesome stuff for Fable and Elmish.<br>
Also Maxime Mangel for his work.<br>
The Team of then SAFE-Stack, which makes it easy to start full stack web applictions.<br>
The Creator of Saturn, for that easy wrapper around ASP.NET and Giraffe.<br>
And Martin36 for this fancy gauge react control.</p>
<p>Resources:</p>
<p>The Project on Github:<br>
<a href="https://github.com/hardt-coded/raspberrypi-safe-stack-thermometer-example">https://github.com/hardt-coded/raspberrypi-safe-stack-thermometer-example</a></p>
<p>The Gauge Control:<br>
<a href="https://github.com/Martin36/react-gauge-chart">https://github.com/Martin36/react-gauge-chart</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[(Video Tutorial) F# - How to build an Electron Desktop App with the F# SAFE Stack and the ElectronNET-Project]]></title><description><![CDATA[<div class="kg-card-markdown"><iframe width="1280" height="720" src="https://www.youtube-nocookie.com/embed/90vXK6a8xxA" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>in this tutorial I will show you how to build an electron desktop app with the F# SAFE Stack and the ElectronNET Project.</p>
<p>For this tutorial I used the Version 1.24.0 of the SAFE Stack. I know there will be a v2 in the near future, but you</p></div>]]></description><link>https://hardt.software/video-tutorial-f-how-to-build-an-electron-desktop-app-with-the-f-safe-stack-and-the-electronnet-project/</link><guid isPermaLink="false">5f2d92cd115de8102469efb2</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Fri, 07 Aug 2020 17:48:39 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><iframe width="1280" height="720" src="https://www.youtube-nocookie.com/embed/90vXK6a8xxA" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>in this tutorial I will show you how to build an electron desktop app with the F# SAFE Stack and the ElectronNET Project.</p>
<p>For this tutorial I used the Version 1.24.0 of the SAFE Stack. I know there will be a v2 in the near future, but you should be able to use the step described in the video as well.</p>
<p>Sadly I runn into an issue with paket, which I solved in there. It's possible, that all runs fine on your machine.</p>
<p>I use Visual Studio, but all other IDE should work fine to.</p>
<p>Resources:</p>
<p>This Tutorial App:<br>
<a href="https://github.com/hardt-coded/safe-stack-electron-net-example">https://github.com/hardt-coded/safe-stack-electron-net-example</a></p>
<p>F# Safe-Stack:<br>
<a href="https://safe-stack.github.io/">https://safe-stack.github.io/</a></p>
<p>ElectronNET Project:<br>
<a href="https://github.com/ElectronNET/Electron.NET">https://github.com/ElectronNET/Electron.NET</a></p>
<p>a sample electron manifest file:<br>
<a href="https://github.com/hardt-coded/safe-stack-electron-net-example/blob/master/src/Server/electron.manifest.json">https://github.com/hardt-coded/safe-stack-electron-net-example/blob/master/src/Server/electron.manifest.json</a></p>
<p>Twitter:<br>
<a href="https://twitter.com/HardtITSolution">https://twitter.com/HardtITSolution</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[F# Applicative - how I get my head around this kind of black magic spell]]></title><description><![CDATA[<div class="kg-card-markdown"><p>When I came the first time in contact with F#, a little more than a year ago, I work myself to some tutorial and code and stuff. And the first time I dicovered some kind of <strong>black magic spell</strong>, where some values, which are wrapped in a result-type or error-type</p></div>]]></description><link>https://hardt.software/applicative-how-i-get-my-head-around-it/</link><guid isPermaLink="false">5e41ae84989fda0db8d7619a</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Mon, 10 Feb 2020 22:04:43 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>When I came the first time in contact with F#, a little more than a year ago, I work myself to some tutorial and code and stuff. And the first time I dicovered some kind of <strong>black magic spell</strong>, where some values, which are wrapped in a result-type or error-type and a function which uses the &quot;normal&quot; values and not the values wrapped in the result type, put together with some magic symbols and we get actually a result out of this. The Spell I mean is:</p>
<pre><code class="language-fsharp">myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue2
</code></pre>
<p>I tried to get my head around this and I failed. It was to much to process as a beginner in F#. I think I used Scott's Blog Post to get it at this time.<br>
<a href="https://fsharpforfunandprofit.com/posts/elevated-world/">https://fsharpforfunandprofit.com/posts/elevated-world/</a> But It didn't help me, because I was to new and maybe to stupid to get it.<br>
I put my effort to learn in other stuff and forget about this topic.</p>
<p>Later I discovered the <code>applicative</code> stuff again (I think it was Scott's cheat sheet on gist and some other code example) and now I thought, maybe I get it now. I learned about Scott's ROP, Monads, computation expressions and all the awesome stuff, that F# has to offer.</p>
<p>So this blog post describe the way I get my head around this topic and how I understand, why this following <strong>Black Magic Spell</strong> actually works.</p>
<h3 id="theblackmagicspell">The Black Magic Spell:</h3>
<pre><code class="language-fsharp">myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue2
</code></pre>
<p>For someone who is new to the functional stuff, even if the developer is a senior  in other programming paradigms, this line of code appears to be some kind of black magic.</p>
<p>On one side, we have our normal function like this:</p>
<pre><code class="language-fsharp">let myfunction (a:int) (b:int) (c:int) =
    a + b + c
</code></pre>
<p>It doesn't take any kind of result-ish parameters. Like <code>Ok 1</code> or <code>Error &quot;ups!&quot;</code>, it uses the values, which are &quot;hidden&quot; in the Result itself. Here in this example 3 integer values.</p>
<p>On the other side, we have actually result-ish values:</p>
<pre><code class="language-fsharp">let resultValue1 = Ok 2
let resultValue2 = Error &quot;ups!&quot;
</code></pre>
<p>Now we put this with some strange symbols together and we get actually our result, wrapped in <code>Result</code>-Datatype.</p>
<h3 id="how">How?</h3>
<p>To understand this, you need to know the concept of partial application. Partial application is the ability to put only a part of the arguments to a function and get a new function back. Also you need to know, how a map function works. In this case the Result.map function.</p>
<h3 id="quickrecap">Quick recap:</h3>
<pre><code class="language-fsharp">// -------------------
// partial application
// -------------------
let add a b =
    a + b
    
// you get a new function with the missing second parameter b
let add10 = add 10  // int-&gt;int

add10 10 // result = 20


//----------------
// map function - Result.map
//----------------

let result1 = Ok 1
let result2 = Error &quot;ups!&quot;

let mappingFunction input =
    input + 10

// this inner Ok value of the Result is run thru the mapping function 
// and returns the result wrapped in an Ok
Result.map mappingFunction result // Result= Ok 11
</code></pre>
<p>As always Scott Wlashin has the reference material<br>
partial application: <a href="https://fsharpforfunandprofit.com/posts/partial-application/">https://fsharpforfunandprofit.com/posts/partial-application/</a></p>
<p>But let us continue...</p>
<h3 id="thesymbols">the Symbols</h3>
<p>to understand this &quot;black magic&quot;, we need to know, what the symbols stand for.</p>
<ol>
<li><code>&lt;!&gt;</code> is the map function or in this case, it stands for the Result.map</li>
<li><code>&lt;*&gt;</code>is the apply function. This function doesn't existis in the FSharp.Core library. This function we have to write on our own.</li>
</ol>
<pre><code class="language-fsharp">let (&lt;!&gt;) = Result.map
let (&lt;*&gt;) = apply
</code></pre>
<p>Okay, the Result.map function takes 2 parameters. The first one, is the mapping function with one parameter <code>a'</code> and the result <code>b'</code>. SO the signature is <code>a' -&gt; b'</code>. The second parameter is the result, which we want to map. The type is <code>Result&lt;'a,error'&gt;</code></p>
<p>With the ability to create our own operators, like <code>&lt;!&gt;</code> in F#, we actually move the parameters from the original Result.map function around this operator. On the left side of our operator, we have the mapping-function our first parameter and on the right side of our operator we have our input the second parameter.</p>
<pre><code class="language-fsharp">let input = Ok 1
let mapping a = a + 10

let res1 = Result.map mapping input
// is the same as
let res2 = mapping &lt;!&gt; input
</code></pre>
<p>So what does this mean to the first part of our &quot;black magic&quot; expression from the beginning:</p>
<pre><code class="language-fsharp">myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue2
</code></pre>
<p>where <code>myfunction</code> is actually:</p>
<pre><code class="language-fsharp">let myfunction (a:int) (b:int) (c:int) =
    a + b + c
</code></pre>
<p>We did following:</p>
<pre><code class="language-fsharp">// myfunnction &lt;!&gt; resultValue1
let firstPart = Result.map myfunction resultValue1
</code></pre>
<p>But stop, our <code>myfunction</code> does have 3 parameters and not one. Map function suppose to have 1 parameter as input, not 3 or more of them.</p>
<p>Here comes the partial application in place. We put a function with 3 paramters into a function with one and get as a result a function with 2 parameters left.<br>
But first, let show how the map work by building a map function of our own:</p>
<pre><code class="language-fsharp">let giveMeAMap (func:int -&gt; 'b) input =
    let res = func input 
    res


giveMeAMap (fun i-&gt; printfn &quot;%i&quot; i) 10 // returns a unit, and prints the 10 on the screen
giveMeAMap (fun i-&gt; i + 100) 10 // returns 110 (it add 100 to our input)
giveMeAMap (fun i-&gt; i.ToString()) 10 // return the string &quot;10&quot;
</code></pre>
<p>You see here our mapping function will be called with our input parameter. So what did we get, if we have a function with multiple parameters as a mapping function? Yes, we apply 1 parameter to this function, our <code>input</code> and get a function with the missing other parameters.</p>
<pre><code class="language-fsharp">// a mapping function 
let mymap a b c = a + b + c // mapping function with 3 parameter
giveMeAMap mymap 10

// you get a function with following signature: int -&gt; int -&gt; int (2 input parameters)
// internally we are running our map function as following:
let res = mymap 10 // we use only one parameter
</code></pre>
<p>And now we have solved the first part of our magic spell from above:</p>
<pre><code class="language-fsharp">myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue2
</code></pre>
<p>or more precisely</p>
<pre><code class="language-fsharp">myfunction &lt;!&gt; resultValue1 ...
</code></pre>
<p>Let solve the first part:</p>
<pre><code class="language-fsharp">let resultValue1 = Ok 10

let myfunction (a:int) (b:int) (c:int) =
    a + b + c
    
// Remember myfunction &lt;!&gt; resultValue1 is like:
let firstPart = Result.map myfunction resultValue1
</code></pre>
<p>we get:<br>
<code>Ok [some function with the signature int-&gt;int-&gt;int]</code><br>
a function wrapped In a result-type</p>
<pre><code>The FSI shows:
[&lt;Struct&gt;]
val firstStep : Result&lt;(int -&gt; int -&gt; int),string&gt; = Ok &lt;fun:Invoke@2697-1&gt;
</code></pre>
<p>Now to the second part of our black magic spell, the <code>apply</code>-function:</p>
<pre><code class="language-fsharp">let apply func input =
    match func,input with
    | Ok f, Ok x -&gt; Ok (func input)  // runs func with the parameter input
    | Error e, _ -&gt; Error e  // return the error if func is already an error
    | _, Error e -&gt; Error e // return the error if the input is an error

// like the map, we make out of the apply function an operator, 
// so the the first parameter, the wrapped function, 
// is on the left side and our second parameter the input is on the right side.
let (&lt;*&gt;) = apply

</code></pre>
<p>The <code>apply</code>-function takes 2 parameters. The first one is a function wrapped in a result-Type. The second one is a value also wrapped in a result-Type.<br>
We check both parameters. If both are okay, we use the <code>inner-function</code> and call it with the value from our second parameters. A little bit, like our map function, but here the <code>mapping</code>-function is wrapped in the result-type.</p>
<p>Wait, a function wrapped in a result type. That is exactly the same thing our map function return in the first part of our &quot;magic spell&quot;.</p>
<p>Okay, before we continue and to complete the <code>apply</code>-function, in case one of the parameters contains an error, the <code>apply</code>-function returns this error.</p>
<p>Now we have all to understand our black magic spell:</p>
<pre><code class="language-fsharp">myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue2
</code></pre>
<p>Let's do it step by step now:</p>
<h3 id="step1themapfunction">Step 1 (the map function):</h3>
<pre><code class="language-fsharp">let firstStep = myfunction &lt;!&gt; resultValue1
// or
let firstStep = Result.map myfunction resultValue1
</code></pre>
<p>we get, as mentions a function (int -&gt; int -&gt; int) wrapped in a result (OK)</p>
<h3 id="step2thefirstappearenceofourapplyfunction">Step 2 (the first appearence of our apply function):</h3>
<pre><code class="language-fsharp">let secondStep = myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1
// or
let secondStep = (myfunction &lt;!&gt; resultValue1) &lt;*&gt; resultValue1
// better
let secondStep = firstStep &lt;*&gt; resultValue1
// or, the same without the operator:
let secondStep = apply firstStep resultValue1
</code></pre>
<p>In this step our function, which came as a result from our first step, will be &quot;unpacked&quot; and called with the next value from the second parameter (our <code>resultValue1</code>). We make another partial application. Because our function from the firstStep has 2 parameters to work with and we apply only one of them. Like here:</p>
<pre><code class="language-fsharp">// function with the signature: int -&gt; int -&gt; int
let nextFunc a b = 
    a + b

let nextFunc10 = nextFunc 10 // resturns a function int-&gt;int
</code></pre>
<p>The apply function here returns a new function with only one parameter left, wrapped in a result-type.</p>
<h3 id="step3anotherapplylaststep">Step 3 (another apply - last step):</h3>
<pre><code class="language-fsharp">let thirdStep = myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue1
// or
let thirdStep = (myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1) &lt;*&gt; resultValue1
// better:
let thirdStep = secondStep &lt;*&gt; resultValue1
// or, the same without the operator:
let thirdStep = apply secondStep resultValue1
</code></pre>
<p>Here we doing the same, as in the step before. We <code>unpack</code> our function, which is return from the second step and which has one input parameter left, and we run it with the unpacked <code>second</code> parameter, our <code>resultValue1</code>.</p>
<p>And with this step our whole <code>back magic spell</code> from above is solved. We get actually our result wrapped in a result-type.</p>
<p>Here again the whole snippet, with all steps inside:</p>
<pre><code class="language-fsharp">let apply f x =
    match f,x with
    | Ok f, Ok x -&gt; Ok (f x)
    | Error e, _ -&gt; Error e
    | _, Error e -&gt; Error e


let (&lt;!&gt;) = Result.map
let (&lt;*&gt;) = apply

let myfunction (a:int) (b:int) (c:int) =
    a + b + c


let resultValue1 = Ok 2
let resultValue2 = Error &quot;ups!&quot;

// returns Error &quot;ups!&quot; because, one of the parameter is an error
let res1:Result&lt;int,string&gt; =
    myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue2

// return Ok 6, because 2 + 2 + 2 is 6 wrapped in an OK
let res2:Result&lt;int,string&gt; =
    myfunction &lt;!&gt; resultValue1 &lt;*&gt; resultValue1 &lt;*&gt; resultValue1


let firstStep:Result&lt;int-&gt;int-&gt;int,string&gt; =
    Result.map myfunction resultValue1

let secondStep:Result&lt;int-&gt;int,string&gt; =
    apply firstStep resultValue1

let thirdStep:Result&lt;int,string&gt; =
    apply secondStep resultValue2
</code></pre>
<p>I hope this explanation helps, it's the way I get my head around this applicative thing.</p>
<p>I know, maybe it is the same as Scott wrote in his blog post and likely he did a better job to describe this topic at all. But this is how I got my head around it later, without to check again the blog post from Scott.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Secure your Webservice with JWT in Saturn and F#]]></title><description><![CDATA[<div class="kg-card-markdown"><p>How do I secure my web service or webapp with a json web token and use the service itself as the one, which also manages the user itself. (no oauth with google or something else.)</p>
<p>I do not explain the JWT at all. I show only step by step, how</p></div>]]></description><link>https://hardt.software/secure-webserivce-with-jwt-saturn-fsharp/</link><guid isPermaLink="false">5dbb4d5d989eca150c0a2c13</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Thu, 31 Oct 2019 22:17:05 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>How do I secure my web service or webapp with a json web token and use the service itself as the one, which also manages the user itself. (no oauth with google or something else.)</p>
<p>I do not explain the JWT at all. I show only step by step, how to implement it in saturn, an awesome mvc f# web framework.</p>
<p>I use the saturn template base app for this tutorial.</p>
<p>I put all the needed code in one module except for the routes. Feel free to order your code, how do you need. For example I use the module name <code>AuthStuff</code>.</p>
<pre><code class="language-fsharp">module AuthStuff
</code></pre>
<p>What do we need.</p>
<h4 id="prepareweneedsomenamespacestoopeninthatfile">Prepare, we need some namespaces to open in that file</h4>
<pre><code class="language-fsharp">open System
open System.Text
open Saturn
open System.Security.Claims
open System.IdentityModel.Tokens.Jwt
open Microsoft.IdentityModel.Tokens
open Microsoft.AspNetCore.Authentication.JwtBearer

</code></pre>
<h4 id="1weneed2recordtypesoneisthemodelforthelogindataandtheotheristhemodelforthetokenreturndata">1. We need 2 record types. One is the model for the login data and the other is the model for the token return data.</h4>
<pre><code class="language-fsharp">type LoginModel ={
    UserName : string
    Password : string
}

type TokenResult ={
    Token : string
}
</code></pre>
<h4 id="2nowweneedsomevalueslikethesecretkeywhichsignsourtokenthekeyitselfhastobeatleast16characterslong128bitalsoanvaluefortheissuerandtheaudiencefeelfreetosearchforyourselfwhatforarethesevalues">2. Now we need some values, like the secret key, which signs our token. The key itself has to be at least 16 characters long  (128 Bit). Also an value for the issuer and the audience. (feel free to search for yourself, what for are these values.)</h4>
<pre><code class="language-fsharp">// min 128 Bit - min 16 character
let secret = &quot;ineeda128bitkey!&quot;
let issuer = &quot;myauthapp.de&quot;
let audience = &quot;myauthapp.de&quot;
</code></pre>
<h3 id="3thenweneedasaturnpipelinetoactivatetheauthenticationfortheroutesthatneededtosecured">3. Then we need a saturn pipeline to activate the authentication for the routes, that needed to secured</h3>
<pre><code class="language-fsharp">open Saturn

let onlyLoggedIn = pipeline {
    requires_authentication  (Giraffe.Auth.challenge JwtBearerDefaults.AuthenticationScheme)
}
</code></pre>
<h4 id="4alsoweneedafunctionwhichgeneratesthejwttokenitself">4. Also we need a function, which generates the JWT Token itself</h4>
<pre><code class="language-fsharp">let generateToken username claims =
    let claims = [|
        Claim(JwtRegisteredClaimNames.Sub, username);
        Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) 
        // here you can implement other claims, which are encoded in the token itself
        yield! claims
    |]

    let expires = Nullable(DateTime.UtcNow.AddHours(8.0))
    let notBefore = Nullable(DateTime.UtcNow)
    let securityKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
    let signingCredentials = SigningCredentials(key = securityKey, algorithm = SecurityAlgorithms.HmacSha256)

    let token =
        JwtSecurityToken(
            issuer = issuer,
            audience = audience,
            claims = claims,
            expires = expires,
            notBefore = notBefore,
            signingCredentials = signingCredentials)

    let tokenResult = {
        Token = JwtSecurityTokenHandler().WriteToken(token)
    }

    tokenResult
</code></pre>
<h4 id="5thenextstepistotellsaturntousejwttokenforauthenticationtodothisweneedtoextendthesaturnapplicationbuilderobjectwithourownfunction">5. The next Step is to tell saturn to use JWT Token for authentication. To do this, we need to extend the Saturn ApplicationBuilder object with our own function</h4>
<pre><code class="language-fsharp">open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.DependencyInjection

type Saturn.Application.ApplicationBuilder with

    [&lt;CustomOperation(&quot;my_own_jwt_auth&quot;)&gt;]
    member __.UseMyMehAuth(state: ApplicationState,secret:string) =
        let middleware (app : IApplicationBuilder) =
            app.UseAuthentication()

        let service (s : IServiceCollection) =
            s.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(fun options -&gt;
                    options.TokenValidationParameters &lt;- TokenValidationParameters(
                        ValidateActor = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = issuer,
                        ValidAudience = audience,
                        IssuerSigningKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)))
                ) |&gt; ignore
            s

        { state with
            ServicesConfig = service::state.ServicesConfig
            AppConfigs = middleware::state.AppConfigs
            CookiesAlreadyAdded = true
        }
</code></pre>
<p>As you see, I use the CustomOperation attribute with ne name <code>my_own_jwt_auth</code>, these is the expression we use in the application setup from you saturn app.<br>
The function itself has 1 extra parameter beside the <code>state</code> (which is a necessary parameter to extend the ApplicationBuilder), and this is the <code>secret</code>. You can use more to make this more flexible, if you want.</p>
<h4 id="6nowweputournewapplicationbuilderextensiontotheapplicationsetupinthisexampleyouseetheappsetupfromthesaturntemplate">6. Now we put our new ApplicationBuilder extension to the application setup. In this example you see the app setup from the saturn template.</h4>
<pre><code class="language-fsharp">open AuthStuff

let app = application {
    pipe_through endpointPipe
    
    // here! you see, this is our extension!
    my_own_jwt_auth AuthStuff.secret

    error_handler (fun ex _ -&gt; pipeline { render_html (InternalError.layout ex) })
    use_router Router.appRouter
    url &quot;http://0.0.0.0:8085/&quot;

    memory_cache
    use_static &quot;static&quot;
    use_gzip
    use_config (fun _ -&gt; {connectionString = &quot;DataSource=database.sqlite&quot;} ) //TODO: Set development time configuration
}
</code></pre>
<h4 id="7sonextstepisactuallyaddaendpointwherewecangetourtokenandoneendpointwhichwesecurefortestingpurposesthiscodeiputinthefilerouterfsfromthebasicsaturntemplateifyouwonder">7. So next step is actually add a endpoint, where we can get our token and one endpoint, which we secure for testing purposes. This code I put in the file &quot;Router.fs&quot; from the basic saturn template, if you wonder.</h4>
<p>The Token Endpoint:</p>
<pre><code class="language-fsharp">let tokenRouter = router {
    post &quot;/gettoken&quot; (fun next ctx -&gt;
        task {
            let! model = ctx.BindJsonAsync&lt;LoginModel&gt;()

            // handle the authentication here itself. So ask the db if the user and password is correct. What ever is needed.

            let tokenResult = 
                AuthStuff.generateToken model.UserName [| (* here add your claims *) |]

            return! json tokenResult next ctx
        })
}
</code></pre>
<p>The Test Endpoint:<br>
Here you see, we are adding out <code>onlyLoggedIn</code> pipeline</p>
<pre><code class="language-fsharp">let authRouter = router {
    pipe_through onlyLoggedIn
    get &quot;/checksec&quot; (fun next ctx -&gt;
        task {
            
            let username = ctx.User.FindFirst ClaimTypes.NameIdentifier
            let txt = sprintf &quot;Hello %s&quot; username.Value

            return! text txt next ctx
        }
    )
}
</code></pre>
<h4 id="8andthelaststepistoaddthe2endpoints">8. And the last Step is to add the 2 endpoints</h4>
<pre><code class="language-fsharp">let appRouter = router {
    // here add the new endpoint
    forward &quot;/hidden&quot; authRouter
    forward &quot;/token&quot; tokenRouter

    forward &quot;&quot; browserRouter
}
</code></pre>
<h4 id="letstestourstuff">Let's test our stuff:</h4>
<p>Send the request to the topken endpoint:</p>
<p><img src="https://hardt.software/content/images/2019/10/postman_saturn_token_request-1.png" alt="postman_saturn_token_request-1"></p>
<p>Now copy the token and use it in the bearer token authentication header:</p>
<p><img src="https://hardt.software/content/images/2019/10/postman_saturn_use_token.png" alt="postman_saturn_use_token"></p>
<p>Havin fun!</p>
</div>]]></content:encoded></item><item><title><![CDATA[Building WebComponents with Fable - Elmish - React]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I see tons of good examples in Fable and build nice web apps with Fable and Elmish and React. But I have a client, which needs to build WebComponents. So I've done some research, it should be possible to build web components with the nice way of Fable Elmish. And</p></div>]]></description><link>https://hardt.software/building-a-webcomponent-with-fable-elmish-react/</link><guid isPermaLink="false">5b6bfd3992d90910e8089ed6</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Thu, 09 Aug 2018 17:53:36 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I see tons of good examples in Fable and build nice web apps with Fable and Elmish and React. But I have a client, which needs to build WebComponents. So I've done some research, it should be possible to build web components with the nice way of Fable Elmish. And it is possible.</p>
<p>But there are some troubles to get t to work. So I write here the Steps to success. Maybe I or someone else can write an extension to Fable encapsulate all the boiler plate stuff.</p>
<h2 id="1createnewprojectwiththefableelmishreactapp">1. Create new project with the fable-elmish-react app</h2>
<p><br>
Create an Fable-Elmish-React Example App with following commands:</p>
<pre><code>dotnet new -i Fable.Template.Elmish.React
dotnet new fable-elmish-react -n mywebcomponent

cd mywebcomponent
yarn
dotnet restore
</code></pre>
<h2 id="2nowtheimportentstuffnowwebuildawebcomponent">2. Now the importent stuff - now we build a webComponent</h2>
<p><br>
After some research, I find out, that you can actually render react stuff in the shadowDOM of a webComponent. In JS style, it looks like:</p>
<pre><code class="language-javascript">class WebComponent extends HTMLElement {
    const mountPoint = document.createElement(&quot;div&quot;);
    const shadowRoot = this.attachShadow({
      mode: &quot;open&quot;
    });
    shadowRoot.appendChild(mountPoint);
    ReactDOM.render(&lt;a href={url}&gt;{name}&lt;/a&gt;, mountPoint);
}

customElements.define('web-component', WebComponent);
</code></pre>
<p>So, it should be possible to implement that only for the nice emlish-react stuff.</p>
<p>How would it look like. Something like this:</p>
<pre><code class="language-fsharp">type WebComponent() =   
    inherit HTMLElement()    
     
    member this.connectedCallback() = 
        let shadowRoot = createShadowRoot()        
        let mountPoint = document.createElement &quot;div&quot;        
        shadowRoot.appendChild mountPoint
        
        // Look this familiar? Yes thats basically the code of the App-init-stuff
        Program.mkProgram init update root 
        |&gt; Program.toNavigable (parseHash pageParser) urlUpdate               
        |&gt; Program.withDebugger
        |&gt; Program.withHMR        
        |&gt; initReact mountPoint
        |&gt; Program.run
        ()

CustomElements.define &quot;web-component&quot;
</code></pre>
<p>Okay, define a class which inherits from an <strong>HTMLElement</strong>.<br>
The method <strong>connectCallback()</strong> is one of the life cycle methods of a webcomponent.<br>
And what we do is run our Program stuff inside this method.</p>
<p>Easy isn't it? Okay, we need some boilerplate stuff. Like &quot;createShadowRoot&quot; or &quot;initReact&quot;.</p>
<h2 id="3theboilerplatestufftotranslatethisintotherightjavascript">3. The Boilerplate Stuff to translate this into the right javascript</h2>
<p><br>
<strong>1. HTMLElement()</strong><br>
Fable has already an interface of HTMLElement. But we don't need this. We need an empty abstract class. We need to flag this as <strong>global</strong> to avoid that this class will be translated.</p>
<pre><code>```fsharp
[&lt;Global&gt;]
type HTMLElement() = class end
```
If we inherit a class from this. Fable will translate this into &quot;class MyClass extends HTMLElement&quot;
</code></pre>
<p><strong>2. createShadowRoot()</strong><br>
Here we use Emit to generate the matching javascript code to create a ShadowDOM root. There is also a createShadowRoot() function in Javascript, but the Polyfill for Browsers, that doesn't support custom elements only recognize this function. (Hint: the type ShadowRoot is defined on No. 4)<br>
<code>fsharp [&lt;Emit(&quot;this.attachShadow({ mode: 'open' });&quot;)&gt;] let createShadowRoot() : ShadowRoot = jsNative</code></p>
<p><strong>3. document.creatElement</strong> is part of Fable</p>
<p><strong>4. shadowRoot.appendChild</strong><br>
Here is the missing ShadowRoot type. Here we defint one member to append a HTMLElement (The Fable interface, not our placeholder in No. 1)<br>
<code>fsharp [&lt;Global&gt;] type ShadowRoot() = [&lt;Emit(&quot;$0.appendChild($1);&quot;)&gt;] member this.appendChild (el:Fable.Import.Browser.HTMLElement) = jsNative</code></p>
<p><strong>5. |&gt; initReact mountPoint</strong><br>
This function will be intiate the ReactDOM.render part. It's a little modified version of the react <strong>Program.withReact&quot;</strong> function.<br>
```fsharp<br>
// Common for the &quot;lazyView2With&quot; function<br>
open Elmish.React.Common</p>
<pre><code>let initReact mountPoint (program:Elmish.Program&lt;_,_,_,_&gt;) =
    let mutable lastRequest = None
    let setState model dispatch =
        Fable.Import.ReactDom.render(
                lazyView2With (fun x y -&gt; obj.ReferenceEquals(x,y)) program.view model dispatch,
                mountPoint
            )
    { program with setState = setState }
```
</code></pre>
<p><strong>6. CustomElements.define</strong><br>
This one is also an &quot;Emit&quot;.<br>
<code>fsharp module CustomElements = [&lt;Emit(&quot;customElements.define($0,WebComponent);&quot;)&gt;] let define (elementName:string) = jsNative</code></p>
<h2 id="4letsrunourcodefirsttry">4. Let's run our code - first try</h2>
<p><br>
Before we run our code, we need to modify the index.html in the public folder. Instead of the <code>&lt;div id=&quot;elmish-app&quot;&gt;&lt;/div&gt;</code> we replace this with: <code>&lt;web-component&gt;&lt;/web-component&gt;</code></p>
<p>So letzt run this with:</p>
<pre><code>cd src
dotnet fable yarn-start
</code></pre>
<p>and goto <a href="http://locahost:8080/">http://locahost:8080/</a></p>
<p>And what did we see? An Error in the console:<br>
<img src="https://hardt.software/content/images/2018/08/20180809_Error_construct_HTMLElement.png" alt="20180809_Error_construct_HTMLElement"><br>
After some research, we need to link the <strong>&quot;custom-elements-es5-adapter.js&quot;</strong> library:</p>
<p>So add the following script tag to the head of the index.html</p>
<pre><code class="language-html">&lt;script src=&quot;https://unpkg.com/@webcomponents/webcomponentsjs@2.0.3/custom-elements-es5-adapter.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>And now. We see some thing, that looks like our elmish app.<br>
<img src="https://hardt.software/content/images/2018/08/20180809_first_view_without_css.png" alt="20180809_first_view_without_css"><br>
But wait, what's happen with the CSS.</p>
<p>After some research, the CSS doesn't leak into the ShadowDOM and vice versa. (The polyfill is maybe an exception to this. But Chrome...)</p>
<p>So what we need is to add our style sheets to the ShadowDOM.</p>
<h2 id="5modifywebpackconfigjstogetaseparatecssfile">5. Modify webpack.config.js to get a separate css file</h2>
<p><br>
At first we need a separate CSS file. Currently it's bundled to the bundle.js.</p>
<p>This is how we change that:</p>
<ol>
<li>Install &quot;extract-text-webpack-plugin&quot; with</li>
</ol>
<pre><code>yarn add extract-text-webpack-plugin
</code></pre>
<ol start="2">
<li>now you have to modify the webpack.config.js</li>
</ol>
<pre><code>var path = require(&quot;path&quot;);
var webpack = require(&quot;webpack&quot;);
var fableUtils = require(&quot;fable-utils&quot;);

// Add these 2 line here !!!
const ExtractTextPlugin = require(&quot;extract-text-webpack-plugin&quot;);
const extractCSS = new ExtractTextPlugin('styles.min.css');

// ...
 ... stuff  ...
 
module: {
    rules: [
        // modify the sass RULE!!! to
        {
            test: /\.sass$/,
            use: extractCSS.extract([                                
                &quot;css-loader&quot;,                    
                &quot;sass-loader&quot;
            ])
        }
    ]
},
plugins: isProduction ? [] : [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(),
        
        // Add these entry to the plugnis array!
        extractCSS
    ]
 
</code></pre>
<p>After the modifications, you have to restart <strong>dotnet fable yarn-start</strong></p>
<p>Now we have our styles.min.css.</p>
<h2 id="6addthecsstotheshadowdomsothatourwebcomponentdoesntlooklikecrap">6. Add the CSS to the ShadowDOM, so that our WebComponent doesn't look like crap</h2>
<p><br>
Inside out <strong>connectedCallback</strong> function we need to add the CSS link.</p>
<p>After we create the ShadowRoot we put these lines into the method</p>
<pre><code class="language-fsharp">
member this.connectedCallback() =         
        let shadowRoot = createShadowRoot()   
        
        // Here these 5 lines !!!
        let style = createStyleSheetElement()        
        style.rel &lt;- &quot;stylesheet&quot;
        style.``type`` &lt;- &quot;text/css&quot;
        style.href &lt;- &quot;styles.min.css&quot;

        shadowRoot.appendChild style
        
        // already in the method
        let mountPoint = document.createElement &quot;div&quot;
</code></pre>
<p>Now we had to define some additional boilerplate, so that Fable translate this for us correctly.<br>
Please read the commentaries for further explanations.</p>
<pre><code class="language-fsharp">
// We need an placeholder for the HTMLLinkElement
// the 3 value members will be filled with the needed informations
[&lt;Global&gt;]
type HTMLLinkElement() =   
  member val rel : string = &quot;&quot; with get,set
  member val ``type`` : string = &quot;&quot; with get,set
  member val href : string = &quot;&quot; with get,set

// the create function
[&lt;Emit(&quot;document.createElement('link');&quot;)&gt;]
let createStyleSheetElement():HTMLLinkElement = jsNative


// Extend the ShadowRoot with the second method!
[&lt;Global&gt;]
type ShadowRoot() = 
    [&lt;Emit(&quot;$0.appendChild($1);&quot;)&gt;]
    member this.appendChild (el:Fable.Import.Browser.HTMLElement) = jsNative
    
    // Extend the ShadowRoot class with this member!
    member this.appendChild (el:HTMLLinkElement) = jsNative
      
      
</code></pre>
<p>Also add the following line to the index.html:</p>
<pre><code class="language-html">&lt;link rel=&quot;stylesheet&quot; href=&quot;styles.min.css&quot; /&gt;
</code></pre>
<p>The font isn't getting right, if you do not add the styles to the index.html. This is something for further research.</p>
<p>So well ... It's looking nice.<br>
<img src="https://hardt.software/content/images/2018/08/20180809_after_css_stuff.png" alt="20180809_after_css_stuff"></p>
<p>If we go to the Counter and press plus or minus, than nothing will happen. Also if we enter our name on the <strong>home</strong> screen. But hey, we can navigate.</p>
<p>So what do we do now?</p>
<h2 id="7theproblemswiththeeventsinsidetheshadowdom">7. The problems with the events inside the ShadowDOM</h2>
<p><br>
After some research, again. It's a problem in React in the ShadowDOM. The React Event have to be retargeted.<br>
Lucky for us, Lukas Bombach published a package to fix this error: (Lukas. Thank you: <a href="https://github.com/LukasBombach">https://github.com/LukasBombach</a>)</p>
<p>Here ist the package: <a href="https://www.npmjs.com/package/react-shadow-dom-retarget-events">https://www.npmjs.com/package/react-shadow-dom-retarget-events</a></p>
<p>So we have to import that library and run <strong>retargetEvents(shadowRoot);</strong> after we rendered the react stuff.</p>
<p>At first, we add a new line at the end of our WebComponent class:</p>
<pre><code class="language-fsharp">
let shadowRoot = createShadowRoot()        
let style = createStyleSheetElement()        

...
... Stuff ...


|&gt; Program.run

// Here we fix the problem
retargetEvents(shadowRoot)

()

</code></pre>
<p>Hey, but we should install at first the missing package:</p>
<pre><code>yarn add react-shadow-dom-retarget-events
</code></pre>
<p>Now we need some boilerplate, so that our little function will run.</p>
<pre><code class="language-fsharp">
[&lt;Import(&quot;default&quot;,&quot;react-shadow-dom-retarget-events&quot;)&gt;]
let retargetEvents shadowDom = jsNative

</code></pre>
<p>After restart <strong>dotnet fable yarn-start</strong>, it works like a charm. Pressing the buttons, our webcomponent works as it should.</p>
<p>If you add a new <code>&lt;web-component&gt;&lt;/web-component&gt;</code> tag in the index.html, you will see, that the web components works independently. With one exception. The navigation is synchronized, because the browser address will be used to navigate.</p>
<p>This (maybe) issue is for another day.</p>
<h2 id="8theattributesofawebcomponent">8. The attributes of a web component</h2>
<p><br>
As you know, you can also add attributes to a web component.<br>
So the idea is, that we modify the init functions to accept parameter. So we can change the initial state of our component with attributes.<br>
So add this &quot;counter-start&quot; attribute to the web-component tag.<br>
And maybe add a second below that without an attribute. like this:</p>
<pre><code class="language-html">&lt;web-component counter-start=&quot;999&quot;&gt;&lt;/web-component&gt;
&lt;web-component&gt;&lt;/web-component&gt;
</code></pre>
<p>For example the inital start value of the counter.</p>
<p>open the State.fs file and adjust the init function and add a new parameter:</p>
<pre><code class="language-fsharp">let init counterStart result =
  let (counter, counterCmd) = Counter.State.init()
  // here we set the new counter value
  let counter = counterStart
  let (home, homeCmd) = Home.State.init()
  let (model, cmd) =
    urlUpdate result
      { currentPage = Home
        counter = counter
        home = home }
  model, Cmd.batch [ cmd
                     Cmd.map CounterMsg counterCmd
                     Cmd.map HomeMsg homeCmd ]
</code></pre>
<p>We can also edit the init function of the counter state itself, so that we give the start value to it. But for the demo purppose this little change is enough.</p>
<p>After we change the init function our code has an error.</p>
<p>Back to our App.fs</p>
<p>We add a new line in out web component function (&quot;this.connectedCallback()&quot;)</p>
<pre><code class="language-fsharp">let counterStart = getAttribute &quot;counter-start&quot;
</code></pre>
<p>This function gives us the value of the attribute.</p>
<p>As always, we nee some boilterplate to let this function work.</p>
<pre><code class="language-fsharp">[&lt;Emit(&quot;this.getAttribute($0);&quot;)&gt;]
let getAttribute (name:string) : string = jsNative  
</code></pre>
<p>In this case I return a string.<br>
We need to parse the string into an int, in order to work as out new init() function parameter.</p>
<pre><code class="language-fsharp">let counterStart = getAttribute &quot;counter-start&quot;
let counterStart' =
    if counterStart = null then 0 else counterStart |&gt; int
</code></pre>
<p>yeah, I know. NULL ! But hey, javascript returns sometimes null. So wrap it in an options or something. For the demo it's enough. (I said that before, or?)</p>
<p>Now we can build a new init function with the new parameter:</p>
<pre><code class="language-fsharp">let counterStart = this.getAttribute &quot;counter-start&quot;
let counterStart' =
    if counterStart = null then 0 else counterStart |&gt; int

// define a new init function 
let init = init counterStart'

Program.mkProgram init update root 

</code></pre>
<p>Now you should see this:<br>
<img src="https://hardt.software/content/images/2018/08/20180809_second_and_attributes.png" alt="20180809_second_and_attributes"></p>
<h2 id="9polyfill">9. Polyfill</h2>
<p><br>
At the end I will also add to scripts to the index.html to polyfill the custom elements and the shadowDOM for browsers like Edge or IE, which aren't currently support web components natively.</p>
<pre><code class="language-html">&lt;script src=&quot;https://unpkg.com/@webcomponents/custom-elements@1.2.0/custom-elements.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/@webcomponents/shadydom@1.1.3/shadydom.min.js&quot;&gt;&lt;/script&gt;
</code></pre>
<h2 id="10alltogether">10. All together ...</h2>
<p><br>
The new State.fs file:</p>
<pre><code class="language-fsharp">module App.State

open Elmish
open Elmish.Browser.Navigation
open Elmish.Browser.UrlParser
open Fable.Import.Browser
open Global
open Types

let pageParser: Parser&lt;Page-&gt;Page,Page&gt; =
  oneOf [
    map About (s &quot;about&quot;)
    map Counter (s &quot;counter&quot;)
    map Home (s &quot;home&quot;)
  ]

let urlUpdate (result: Option&lt;Page&gt;) model =
  match result with
  | None -&gt;
    console.error(&quot;Error parsing url&quot;)
    model,Navigation.modifyUrl (toHash model.currentPage)
  | Some page -&gt;
      { model with currentPage = page }, []

let init counterStart result =
  let (counter, counterCmd) = Counter.State.init()
  let counter = counterStart
  let (home, homeCmd) = Home.State.init()
  let (model, cmd) =
    urlUpdate result
      { currentPage = Home
        counter = counter
        home = home }
  model, Cmd.batch [ cmd
                     Cmd.map CounterMsg counterCmd
                     Cmd.map HomeMsg homeCmd ]

let update msg model =
  match msg with
  | CounterMsg msg -&gt;
      let (counter, counterCmd) = Counter.State.update msg model.counter
      { model with counter = counter }, Cmd.map CounterMsg counterCmd
  | HomeMsg msg -&gt;
      let (home, homeCmd) = Home.State.update msg model.home
      { model with home = home }, Cmd.map HomeMsg homeCmd

</code></pre>
<p>The new App.fs</p>
<pre><code class="language-fsharp">module App.View

open Elmish
open Elmish.Browser.Navigation
open Elmish.Browser.UrlParser
open Fable.Core
open Fable.Core.JsInterop
open Fable.Import
open Fable.Import.Browser
open Types
open App.State
open Global

importAll &quot;../sass/main.sass&quot;

open Fable.Helpers.React
open Fable.Helpers.React.Props

let menuItem label page currentPage =
    li
      [ ]
      [ a
          [ classList [ &quot;is-active&quot;, page = currentPage ]
            Href (toHash page) ]
          [ str label ] ]

let menu currentPage =
  aside
    [ ClassName &quot;menu&quot; ]
    [ p
        [ ClassName &quot;menu-label&quot; ]
        [ str &quot;General&quot; ]
      ul
        [ ClassName &quot;menu-list&quot; ]
        [ menuItem &quot;Home&quot; Home currentPage
          menuItem &quot;Counter sample&quot; Counter currentPage
          menuItem &quot;About&quot; Page.About currentPage ] ]

let root model dispatch =

  let pageHtml =
    function
    | Page.About -&gt; Info.View.root
    | Counter -&gt; Counter.View.root model.counter (CounterMsg &gt;&gt; dispatch)
    | Home -&gt; Home.View.root model.home (HomeMsg &gt;&gt; dispatch)

  div
    []
    [ div
        [ ClassName &quot;navbar-bg&quot; ]
        [ div
            [ ClassName &quot;container&quot; ]
            [ Navbar.View.root ] ]
      div
        [ ClassName &quot;section&quot; ]
        [ div
            [ ClassName &quot;container&quot; ]
            [ div
                [ ClassName &quot;columns&quot; ]
                [ div
                    [ ClassName &quot;column is-3&quot; ]
                    [ menu model.currentPage ]
                  div
                    [ ClassName &quot;column&quot; ]
                    [ pageHtml model.currentPage ] ] ] ] ]

open Elmish.React
open Elmish.Debug
open Elmish.HMR

type WebComponent() =   
    inherit HTMLElement()    
     
    member this.connectedCallback() =         
        let shadowRoot = createShadowRoot()        
        let style = createStyleSheetElement()        
        style.rel &lt;- &quot;stylesheet&quot;
        style.``type`` &lt;- &quot;text/css&quot;
        style.href &lt;- &quot;styles.min.css&quot;

        shadowRoot.appendChild style

        let mountPoint = document.createElement &quot;div&quot;        
        shadowRoot.appendChild mountPoint

        let counterStart = getAttribute &quot;counter-start&quot;
        let counterStart' =
            if counterStart = null then 0 else counterStart |&gt; int
        
        let init = init counterStart'

        // Look this familiar? Yes thats basically the code of the App-init-stuff
        Program.mkProgram init update root 
        |&gt; Program.toNavigable (parseHash pageParser) urlUpdate               
        |&gt; Program.withDebugger
        |&gt; Program.withHMR        
        |&gt; initReact mountPoint
        |&gt; Program.run

        retargetEvents(shadowRoot)
        ()

CustomElements.define &quot;web-component&quot;
</code></pre>
<p>The boilerplate stuff in the WebComponents.fs</p>
<pre><code class="language-fsharp">module WebComponents

    open Fable.Core
    open Fable.Core.JsInterop
    open Fable.Import
    open Fable.Import.Browser
    open Elmish.React.Common
    open Fable.Import.React

    module CustomElements =    
        [&lt;Emit(&quot;var res = customElements.define($0,WebComponent);console.log(res)&quot;)&gt;]
        let define (elementName:string) = jsNative

    [&lt;Global&gt;]
    type HTMLElement() = class end

    [&lt;Global&gt;]
    type HTMLLinkElement() =   
      member val rel : string = &quot;&quot; with get,set
      member val ``type`` : string = &quot;&quot; with get,set
      member val href : string = &quot;&quot; with get,set

    [&lt;Global&gt;]
    type ShadowRoot() = 
        [&lt;Emit(&quot;$0.appendChild($1);&quot;)&gt;]
        member this.appendChild (el:Fable.Import.Browser.HTMLElement) = jsNative
        member this.appendChild (el:HTMLLinkElement) = jsNative

    // import retargetEvents from 'react-shadow-dom-retarget-events';
    [&lt;Import(&quot;default&quot;,&quot;react-shadow-dom-retarget-events&quot;)&gt;]
    let retargetEvents shadowDom = jsNative
    
    [&lt;Emit(&quot;this.getAttribute($0);&quot;)&gt;]
    let getAttribute (name:string) : string = jsNative    

    [&lt;Emit(&quot;this.attachShadow({ mode: 'open' });&quot;)&gt;]    
    let createShadowRoot() : ShadowRoot = jsNative      

    [&lt;Emit(&quot;document.createElement('link');&quot;)&gt;]
    let createStyleSheetElement():HTMLLinkElement = jsNative

    let initReact mountPoint (program:Elmish.Program&lt;_,_,_,_&gt;) =
        let mutable lastRequest = None
        let setState model dispatch =
            Fable.Import.ReactDom.render(
                    lazyView2With (fun x y -&gt; obj.ReferenceEquals(x,y)) program.view model dispatch,
                    mountPoint
                )
        { program with setState = setState }
</code></pre>
<p>The new index.html</p>
<pre><code class="language-fsharp">&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Elmish Fable App&lt;/title&gt;
  &lt;meta http-equiv='Content-Type' content='text/html; charset=utf-8'&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  &lt;link rel=&quot;shortcut icon&quot; type=&quot;image/png&quot; href=&quot;img/favicon-32x32.png&quot; sizes=&quot;32x32&quot; /&gt;
  &lt;link rel=&quot;shortcut icon&quot; type=&quot;image/png&quot; href=&quot;img/favicon-16x16.png&quot; sizes=&quot;16x16&quot; /&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css&quot; /&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;styles.min.css&quot; /&gt;
  &lt;script src=&quot;https://cdn.polyfill.io/v2/polyfill.js?features=es6&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/@webcomponents/webcomponentsjs@2.0.3/custom-elements-es5-adapter.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/@webcomponents/custom-elements@1.2.0/custom-elements.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/@webcomponents/shadydom@1.1.3/shadydom.min.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;web-component counter-start=&quot;999&quot;&gt;&lt;/web-component&gt;
  &lt;web-component&gt;&lt;/web-component&gt;
  &lt;script src=&quot;bundle.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h2 id="11yeah">11. Yeah!</h2>
<p><br>
So I hope I could helped someone with this. In my case, I maybe will try to develop this idea any further and mayber I can use it for a customer in the future.</p>
<p>And I hope that I will deploy the code on Github.</p>
<p>If you have any critics, questions or other things, please contact me.</p>
<p>Daniel</p>
</div>]]></content:encoded></item><item><title><![CDATA[F# and ClickOnce - The problems I ran into and how to solve these]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Recently I had a problem to deploy a F# WPF tool with ClickOnce. Yeah ClickOnce, old technology and it's still in use in some enterprises to deploy applications. The standard ClickOnce tab in the project are missing in the project template from Visual Studio. So I had to do some</p></div>]]></description><link>https://hardt.software/f-and-clickonce/</link><guid isPermaLink="false">5b6aa0e792d90910e8089ed5</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Wed, 08 Aug 2018 10:11:07 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Recently I had a problem to deploy a F# WPF tool with ClickOnce. Yeah ClickOnce, old technology and it's still in use in some enterprises to deploy applications. The standard ClickOnce tab in the project are missing in the project template from Visual Studio. So I had to do some research and I found out, that with FAKE you can deploy a F# program via ClickOnce.</p>
<p>At first I want to thanks the authors of 2 blog entries...</p>
<p><a href="https://fwaris.wordpress.com/2013/08/14/fake-script-for-clickonce-packaging-of-f-apps/">https://fwaris.wordpress.com/2013/08/14/fake-script-for-clickonce-packaging-of-f-apps/</a></p>
<p>and</p>
<p><a href="https://github.com/magicmonty/blog/blob/master/_posts/2016-04-15-creating-clickonce-installers-with-fake.md">https://github.com/magicmonty/blog/blob/master/_posts/2016-04-15-creating-clickonce-installers-with-fake.md</a></p>
<p>... for doing all the heavy lifting.</p>
<p>But I won't write a blog article about it, when this was all to do.</p>
<p>I run into 2 Problems:</p>
<ol>
<li>The FAKE Script doesn't find my MSBuild to build the project</li>
<li>The Installation of the programm ends with an error: <em>&quot;Reference in the manifest does not match the identity of the downloaded assembly your-app.exe.&quot;</em></li>
</ol>
<h2 id="thesolutions">The Solutions:</h2>
<h3 id="1msbuildnotfound">1. MSBuild not found</h3>
<p>That's an easy one. Use the following line in your FAKE-Script:</p>
<pre><code class="language-fsharp">setBuildParam &quot;MSBuild&quot; &quot;&lt;your-path-to-vs&gt;\Microsoft Visual Studio/2017/MSBuild/15.0/Bin/MsBuild.exe&quot;
</code></pre>
<h3 id="2thereferenceinthemanifestdoesnotmatch">2. The Reference in the manifest does not match ...</h3>
<p>So this one was a little harder. The solution is to not add the manifest into the assembly.</p>
<p>Normally in the project setting you have a drop down in the &quot;Application&quot; tab, which says <strong>&quot;Create application without a manifest&quot;</strong>.</p>
<p>See here: <a href="https://stackoverflow.com/questions/5337458/error-deploying-clickonce-application-reference-in-the-manifest-does-not-match">https://stackoverflow.com/questions/5337458/error-deploying-clickonce-application-reference-in-the-manifest-does-not-match</a></p>
<p><img src="https://hardt.software/content/images/2018/08/20180808_csproj_option_without_manifest.png" alt="20180808_csproj_option_without_manifest"></p>
<p>This option doesn't exist in the project settings of a F# project. So I look into a csproj file and find this following settings in the project file is there.</p>
<pre><code>&lt;PropertyGroup&gt;
    &lt;NoWin32Manifest&gt;true&lt;/NoWin32Manifest&gt;
&lt;/PropertyGroup&gt;
</code></pre>
<p>I add this setting to the fsproj file and it doesn't work. Damn.</p>
<p>After some further research I find out, that you can also add a compiler flag to avoid that the manifest is embedded into the .exe file.</p>
<pre><code>--nowin32manifest
</code></pre>
<p>So I add this flag in the <strong>&quot;Build&quot;</strong> tab under <strong>&quot;other flags:&quot;</strong>.</p>
<p><img src="https://hardt.software/content/images/2018/08/20180808_other_flags_nowin32manifest.png" alt="20180808_other_flags_nowin32manifest"></p>
<p>Now it work, as it should.</p>
<h3 id="hereistheclickoncedeploymentscript">Here is the ClickOnce Deployment Script</h3>
<p>I do not use FAKE 5, I use FAKE 4. But maybe I migrate this script to FAKE 5 in the future.</p>
<pre><code class="language-fsharp">#r @&quot;.\packages\FAKE.4.64.13\tools\FakeLib.dll&quot;

open Fake

// project and version info
let projectName = &quot;&lt;your-app-name-without-.exe&gt;&quot;
// use your own version
let version = &quot;1.0.0.0&quot;

// Directories
let buildDir  = @&quot;.\build\&quot;
let deployDir = @&quot;.\deploy\&quot;
let applicationDirName = (sprintf &quot;%s.%s&quot; projectName version)
let publishDir = deployDir @@ applicationDirName

// here is set the ClickOnce sign certificate
let cert = @&quot;.\ClickOnce.pfx&quot;
let certPwFile = @&quot;.\ClickOncePwd.txt&quot;

// Set the MSBuild path
setBuildParam &quot;MSBuild&quot; &quot;M:\Microsoft Visual Studio/2017/MSBuild/15.0/Bin/MsBuild.exe&quot;

// Filesets
let appReferences  = !! &quot;&lt;your-project-to-publish-folder&gt;/*.fsproj&quot;


let EmptyMageParams =  { 
    // maybe the mage is in an other folder on your computer
    ToolsPath = @&quot;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools&quot;
    Manifest = &quot;&quot;
    ApplicationFile = &quot;&quot;
    CertFile = None

    Name = projectName
    Version = version
    Processor = MSIL
    TrustLevel = None
    
    // Set here your company name
    Publisher = Some &quot;MyAwesomeCompany&quot;
    
    ProviderURL = &quot;&quot;
    SupportURL = None
    FromDirectory = &quot;&quot;

    ProjectFiles = []
    IconPath = &quot;&quot;
    IconFile = &quot;&quot;
    TmpCertFile = &quot;&quot;
    Password = None
    CertHash = None
    IncludeProvider = None
    Install = None
    UseManifest = None
    CodeBase = None }


#r &quot;System.Xml.Linq.dll&quot;
open System.Xml.Linq

let setUpdatePolicy (filename: string) =
    let n nameSpace name = XName.op_Implicit (nameSpace + name)

    let asmv1 = &quot;{urn:schemas-microsoft-com:asm.v1}&quot;
    let asmv2 = &quot;{urn:schemas-microsoft-com:asm.v2}&quot;
    let cov1 = &quot;{urn:schemas-microsoft-com:clickonce.v1}&quot;

    let removeNode name (node: XElement option) =
        match node with
        | None -&gt; None
        | Some n -&gt;
            match n.Element(name) with
            | null -&gt; ()
            | e -&gt; e.Remove()
            node

    let addNode (name: XName) (node: XElement option) =
        match node with
        | Some n -&gt; n.Add(new XElement(name))
        | _ -&gt; ()

    let element name (node: XElement option) : XElement option =
        match node with
        | None -&gt; None
        | Some n -&gt;
            match n.Element(name) with
            | null -&gt; None
            | e -&gt; Some e

    let doc = XDocument.Load(filename)

    Some doc.Root
    |&gt; element (n asmv2 &quot;deployment&quot;)
    |&gt; element (n asmv2 &quot;subscription&quot;)
    |&gt; element (n asmv2 &quot;update&quot;)
    |&gt; removeNode (n asmv2 &quot;expiration&quot;)
    |&gt; addNode (n asmv2 &quot;beforeApplicationStartup&quot;)

    doc.Save(filename)


Target &quot;Clean&quot; (fun _ -&gt;
    CleanDirs [buildDir; deployDir; publishDir]
)

Target &quot;Build&quot; (fun _ -&gt;
    MSBuildRelease buildDir &quot;Build&quot; appReferences
    |&gt; Log &quot;Release Build-Output: &quot;
)

Target &quot;Prepare Deployment&quot; (fun _ -&gt;
    !! (buildDir @@ &quot;**/*.*&quot;)   
    -- &quot;**/*.pdb&quot;
    -- &quot;**/*.xml&quot;
    |&gt; CopyFiles publishDir
)

Target &quot;Create ClickOnce Installer&quot; (fun _ -&gt;
    let appManifest = publishDir @@ (sprintf &quot;%s.exe.manifest&quot; projectName)
    let deployManifest = sprintf &quot;%s.application&quot; projectName
    let appParams = { EmptyMageParams with Manifest = appManifest
                                           ApplicationFile = publishDir @@ (sprintf &quot;%s.exe&quot; projectName)
                                           TrustLevel = Some FullTrust
                                           FromDirectory = publishDir
                                           IconPath = publishDir
                                           IconFile = projectName + &quot;.ico&quot;
                                           IncludeProvider = Some false
                                           UseManifest = Some true
                                           CertFile = Some cert
                                           Password = Some certPwFile}

    

    let deployParams = { EmptyMageParams with Manifest = appManifest
                                              ApplicationFile = deployDir @@ deployManifest
                                              Install = Some true 
                                              CertFile = Some cert
                                              Password = Some certPwFile }
    
    // Create
    MageCreateApp appParams
    // Sign
    MageSignManifest appParams
    // Deploy
    MageDeployApp deployParams
    
    deployDir @@ deployManifest |&gt; setUpdatePolicy
    // Sign
    MageSignDeploy deployParams

    (buildDir) |&gt; CopyFile publishDir
)

Target &quot;Deploy&quot; (fun _ -&gt;
    trace &quot;Deploy the created ClickOnce installer wherever you want&quot;
)

&quot;Clean&quot;
  ==&gt; &quot;Build&quot;
  ==&gt; &quot;Prepare Deployment&quot;
  ==&gt; &quot;Create ClickOnce Installer&quot;
  ==&gt; &quot;Deploy&quot;

RunTargetOrDefault &quot;Deploy&quot;
</code></pre>
<p>I hope it helps a little.</p>
</div>]]></content:encoded></item><item><title><![CDATA[F# - railway-oriented-programming, my beef with seq<Result<'a,'e>> to Result<'a seq,'e>]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I recently worked with Scott Wlaschins (<a href="https://fsharpforfunandprofit.com/">fsharpforfunandprofit.com</a>) Railway-oriented programming.</p>
<p>I have a mapping function, which maps a eventDTO to a event. For handling the validation, i use also Scotts approach to define special types for the properties of my command. (look <a href="https://fsharpforfunandprofit.com/posts/designing-with-types-more-semantic-types/">here</a>)</p>
<p>So leave the fact, that a validation</p></div>]]></description><link>https://hardt.software/f-from-seq-result-a-e-to-result-a-seq-e/</link><guid isPermaLink="false">5b0c60ed846e7005640e3147</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Mon, 28 May 2018 21:04:56 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I recently worked with Scott Wlaschins (<a href="https://fsharpforfunandprofit.com/">fsharpforfunandprofit.com</a>) Railway-oriented programming.</p>
<p>I have a mapping function, which maps a eventDTO to a event. For handling the validation, i use also Scotts approach to define special types for the properties of my command. (look <a href="https://fsharpforfunandprofit.com/posts/designing-with-types-more-semantic-types/">here</a>)</p>
<p>So leave the fact, that a validation of events from the eventstore maybe makes no sence, because the stored events are defined and stored by the domain. But I went this way and walk right into a &quot;problem&quot;.</p>
<p>For example I have an event like this:</p>
<pre><code class="language-fsharp">
    // event on domain layer
    type ProductCreated = {
        Id:ProductId
        Name:String100
        Description:String2000
        Price:Price
        Weight:Weight      
    }
    
    // event dto for storing in eventStore
    type ProductCreatedEvent = {
        Id:Guid
        Name:string
        Description:string
        Price:decimal
        Weight:decimal      
    }
</code></pre>
<p>So I have defined fitting contraints for <strong>ProductId, String50, String2000, Price</strong> and <strong>Weight</strong>. (You will see more in another article in later times)</p>
<p>Now I have a function which maps the raw event from the eventstore to the event of the domain:</p>
<pre><code class="language-fsharp">
let mapEventToDomain (dto:obj):Result&lt;Event,string&gt; =
    result {
        match dto with
        | :? ProductCreatedEvent as cmd -&gt; 
            let! id = cmd.Id |&gt; ProductId.create
            let! name = cmd.Name |&gt; String100.create &quot;Name&quot;
            let! description = cmd.Description |&gt; String2000.create  &quot;Description&quot;            
            let! weight = cmd.Weight |&gt; Weight.create
            let! price = cmd.Price |&gt; Price.create

            return ProductCreated {
                Id=id
                Name=name
                Description=description                
                Weight=weight
                Price=price                
            }
        | ... // and so on        
   }

</code></pre>
<p>As you see, the function returns a Result&lt;Event,string&gt;, where the <strong>&quot;Event&quot;</strong> is actually a discriminated union and the <strong>&quot;string&quot;</strong> is the error message.</p>
<p>So when I load the events from the eventstore and map the events into the events of the domain layer like this:</p>
<pre><code class="language-FSharp">
// results in seq&lt;Result&lt;Event,string&gt;&gt;
let events = loadFromEventFromEventStore
             |&gt; Seq.map mapEventsToDomain
             

</code></pre>
<p>I get a sequence of results. So how map these to a Result&lt;Event seq,string&gt; (or in generic form Result&lt;'a seq,'e&gt;).</p>
<p>So i decided to fold this things like that:</p>
<pre><code class="language-FSharp">
    let resultFolder (state:Result&lt;'a seq,'c&gt;) (item:Result&lt;'a,'c&gt;) =
        match state,item with
        |Ok x,Ok y -&gt; Ok (seq {yield! x;yield y })
        |Error x, Ok _ -&gt; Error x
        |Ok _, Error y -&gt; Error y
        |Error x,Error _ -&gt; Error x


    let fold list =                
        (Ok Seq.empty,list) ||&gt; Seq.fold resultFolder

</code></pre>
<p>The initial state of the fold is and &quot;okay&quot; empty sequence -&gt; <strong>&quot;Ok Seq.empty&quot;</strong>. This and the list of <strong>Results</strong> will be folded.</p>
<p>So the <strong>&quot;Folder&quot;</strong> function check via pattern match if the current state is okay and the next item is okay. If that's the case I concatenate the item to the state, which is in that case a sequence. In all other cases I will set to the state to an <strong>Error</strong>. If the actual state is already on <strong>&quot;Error&quot;</strong> than I leave this error in that case intact.</p>
<p>You can also modify the folder a little bit, to accumulate the validation errors. Maybe you return a seq of string as errors or you add the messages with a line feed or something:</p>
<pre><code class="language-FSharp">
    // with seq of error
    let resultFolder (state:Result&lt;'a seq,'c seq&gt;) (item:Result&lt;'a,'c&gt;) =
        match state,item with
        |Ok x,Ok y -&gt; Ok (seq {yield! x;yield y })
        |Error x, Ok y -&gt; Error (seq { yield! x })
        |Ok _, Error y -&gt; Error (seq { yield y })
        |Error x,Error y -&gt; Error (seq {yield! x;yield y })

    // with linefeed string
    let resultFolder (state:Result&lt;'a seq,string&gt;) (item:Result&lt;'a,string&gt;) =
        match state,item with
        |Ok x,Ok y -&gt; Ok (seq {yield! x;yield y })
        |Error x, Ok y -&gt; Error x
        |Ok _, Error y -&gt; Error y
        |Error x,Error y -&gt; Error (sprintf &quot;%s\r\n%s&quot; x y)   

</code></pre>
<p>So want I need to know is, how do I get my nice &quot;fold&quot; function as a <strong>CustomOperation</strong> into my <strong>&quot;result&quot; comutation expression</strong>. I tried this with the CustomOperation-Attribute, but than I don't know, how to use this nicely inside my result { }. Maybe someone of you has an idea.</p>
<p>Have a nice day or night or something.</p>
</div>]]></content:encoded></item><item><title><![CDATA[F# - a "simple" math formula solver or my first steps learning F#]]></title><description><![CDATA[<div class="kg-card-markdown"><p>As i earlier mentioned in my blog, F# is an awesome language and i want to try to build a domain logic with it. So I began to port an older ecommerce project of mine to F# with all the nice things like DDD, CQRS and Eventsourcing (or should I</p></div>]]></description><link>https://hardt.software/f-a-simple-math-formula-solver/</link><guid isPermaLink="false">5b019efbf568e91c8c7bbdef</guid><category><![CDATA[F#]]></category><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Sun, 20 May 2018 21:43:10 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>As i earlier mentioned in my blog, F# is an awesome language and i want to try to build a domain logic with it. So I began to port an older ecommerce project of mine to F# with all the nice things like DDD, CQRS and Eventsourcing (or should I say <strong>&quot;Ereignisquellenspeicherung&quot;</strong> - at this current time Greg's favorite word, and i am responsible for that. :D )</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="de" dir="ltr">Ereignisquellenspeicherung is my new favourite word.</p>&mdash; gregyoung (@gregyoung) <a href="https://twitter.com/gregyoung/status/997752510386388992?ref_src=twsrc%5Etfw">May 19, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="en"><p lang="de" dir="ltr">Event-Sourcing = Ereignisquellenspeicherung :D<br>CQRS = Befehls- und Abfragenverantwortungsteilung :D<br><br>Muhahaha</p>&mdash; DieselMeister (@DieselMeister) <a href="https://twitter.com/DieselMeister/status/989040765799190529?ref_src=twsrc%5Etfw">April 25, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Nevertheless, while i am porting my old project in my spare free time, i got to a requirement that the admin can add a formula to a product, which will set the actual price of the product, based on a so called &quot;base price&quot;.</p>
<p>So for example: the awesome product hast a base price of <strong>100 €</strong> and the admin will add some formula like <strong>&quot;base * 1.05&quot;</strong>, so the actual price of the awesome product will be <strong>105 €</strong>.</p>
<p>There are hundreds of math formula solvers i think and i had a open source F# math solver in the first place. but this wasn't compatible with .NET Core. So i decided, that it is a good lesson to write an math formula solver on my own. It is a good exercise and a I'll be able to blog about my experience.</p>
<p>I know there is nice parsing stuff in F#, but in that case I use Regex. But i will learn the parser later on.</p>
<p>So easy enough i thought and so i started to build a very simple formula solver in F#. The solver should work with plus, minus, multiply, divide and power. So my first approach was so simple, that it doesn't accept the simplest math rule: order before multiply and divide before plus and minus. So my second approach, which i describe soon in this post, should work with the simple math rule. And to complete this, yeah i add the support of brackets to it.</p>
<p>so what are the rules of the simple math solver?</p>
<ul>
<li>obey the simple order rule of math</li>
<li>add the ability to use special &quot;symbols/placeholders&quot; like in the example &quot;base&quot; for the base price or something else like the exchange value of bitcoin or the current platin price or something.</li>
</ul>
<p>First at all, i am new in F# and maybe i did something wrong or clumsy or dirty or way too complicated or even totally wrong. But it works and there is always room for improving. So please give me feedback.</p>
<p>Note: the solver has a problem with multiple power operations. So instead to resolve <strong>2^2^3 to 256</strong>, it resolves it to <strong>64</strong>. Because it resolves the formula from left to right and this edge case is not relevant in the domain. Maybe someone of you has a simple way to implement that.</p>
<p>So how should this solver works?</p>
<p>So basically and in my first try (the one without the order to solve math formula), i split the formula into pairs of a symbol and a value. And to be consistent, i add a leading <strong>&quot;+&quot;</strong> to the front of the formula, if there is a positive number. (in case of a negative first number, i had already a symbol)</p>
<pre><code>1 + 2 * 3 - 4 / 5 -&gt;
(+,1)
(+,2)
(*,3)
(-,4)
(/,5)

// or in case of a negative number

-1 + 2 * 3 -&gt;
(-,1)
(+,2)
(*,3)
</code></pre>
<p>so this was it, if you don't want to have the correct order of operations in math. one function to replace any symbols like &quot;base&quot; with a value is not a problem.</p>
<p>I am using the <a href="https://github.com/fsprojects/FSharp.Text.RegexProvider">RegexTypeProvider</a>, if you wonder.</p>
<p><em>Listing split formula into pairs:</em></p>
<pre><code class="language-fsharp">
    type MathPairRegex = 
        Regex&lt; @&quot;(?&lt;MathSymbol&gt;[\+\-\*\/\^])(?&lt;Number&gt;[\-]*[0-9.]*)&quot; &gt;
    type IsMathSymbolRegex = 
        Regex&lt; @&quot;[\+\-\*\/\^\(\)]&quot; &gt;
    
    let isMathSymbol (input:char) =
            IsMathSymbolRegex().IsMatch(input.ToString())

    let tryAddLeadingPlus (formula:string) =
        let isFirstCharMath = formula.[0] |&gt; isMathSymbol           
        if isFirstCharMath then formula 
        else &quot;+&quot; + formula
        
    let splitFormula (formula:string) = 
        formula        
        |&gt; tryAddLeadingPlus
        |&gt; MathPairRegex().TypedMatches        
        |&gt; Seq.map (fun i -&gt; (i.MathSymbol.Value,i.Number.Value)) 

</code></pre>
<p>As in F# you read from bottom to top. So the function at the bottom do what it's named for, and split the formula into the symbol and value pairs. In case of a mission math symbol at the front of the formula, the &quot;tryAddLeadingPlus&quot; function adds a + if it's necessary.</p>
<p>The nice thing of TypeProviders is, that it gives us property names from our data source. So in the SQL TypeProvider you get table names and table cloumns names as properties in your code.<br>
In this case you get the named groups in the Regex as properties.</p>
<p>You will find <strong>&quot;?&lt;MathSymbol&gt;&quot;</strong> and <strong>&quot;?&lt;Number&gt;&quot;</strong> in the mapping function <strong>i.MathSymbol.Value</strong> and <strong>i.Number.Value</strong>. (Note: I called the value from the symbol and value pair here number, because it seems confusing, when i use <strong>&quot;Value&quot;</strong> as name in the Regex. It would end as <strong>i.Value.Value</strong>. That's not pretty.)</p>
<p>Now write a calculate function and the very simple solver is done.</p>
<p><em>Listing calculate sequence of symbol/value pairs:</em></p>
<pre><code class="language-fsharp">
    let usCulture = new CultureInfo(&quot;en-us&quot;)

    let (|ParsedDecimal|) value =
        Decimal.Parse(value,usCulture)

    let calculate (symbolValues:(string * string) seq) =
        (0.0m,symbolValues)
        ||&gt; Seq.fold (fun state item -&gt;
            match item with
            |(&quot;+&quot;,(ParsedDecimal value)) -&gt;                
                state + value
            |(&quot;-&quot;,(ParsedDecimal value)) -&gt;
                state - value
            |(&quot;*&quot;,(ParsedDecimal value)) -&gt;
                state * value
            |(&quot;/&quot;,(ParsedDecimal value)) -&gt;
                state / value
            |(&quot;^&quot;,(ParsedDecimal value)) -&gt;
                (decimal ((float state) ** (float value)))
            | _ -&gt; state
            
            )

</code></pre>
<p>So the calculate function gets a sequence of symbol/value pairs and fold it to the result.<br>
The C# developer knows &quot;fold&quot; as the &quot;Aggregate&quot;-Function in LINQ. So fold iterate to the sequence and perform a function that return the next &quot;state&quot; for the next item in the sequence.<br>
&quot;fold&quot; needs a initial &quot;state&quot; a list of items and the function to perform.<br>
In the case of the fold function i love the ||&gt; (double pipe) operator, because it make the fold function more readable.</p>
<pre><code class="language-fsharp">
// without pipe
Seq.fold (fun state item -&gt; // bla ...) initialState sequence

// with single pipe
sequence |&gt; Seq.fold (fun state item -&gt; // bla ...) initialState

// with the double pipe
(initialState,sequence) ||&gt; Seq.fold (fun state item -&gt; // bla ...)

</code></pre>
<p>See it for your self: if i had to describe the behavior, i would say: &quot;Take the initial state and the sequence and fold it with &quot;bla&quot;.&quot;</p>
<p>So the next thing I use is a ActivePattern. With an ActivePattern you are able to perform operation to a value you want to math in a pattern match.<br>
In that case i parse the Value from string to decimal, so i can use it directly and do the needed operation. I also need the us-en culture, because here in germany the decimal parser will use our number system and would parse &quot;1.00&quot; into &quot;100&quot;, because we use &quot;,&quot; as decimal not &quot;.&quot;</p>
<h4 id="heyandtheexternalsymbolslikebaseoderbitcoinrateorplatinrateorsomething">Hey, and the external symbols like &quot;base&quot; oder &quot;bitcoinRate&quot; or &quot;PlatinRate&quot; or something?</h4>
<p>i almost forget but it is very simple to do that.</p>
<p><em>Listing replace external symbol with values:</em></p>
<pre><code class="language-fsharp">
    type SymbolToValue = SymbolToValue of string * decimal

    let replaceSymbols symbolToValueList formula =
        (formula,symbolToValueList) 
        ||&gt; List.fold (fun (state:string) (item:SymbolToValue) -&gt;
            let (SymbolToValue (symbol,value)) = item
            state.Replace(symbol,value.ToString(usCulture))
            ) 

</code></pre>
<p>So this function replaces all external symbols with values. So the input parameter is a list of symbol to values and the formula. This function iterates the list of symbols and fold with a string replace, so that in the end all symbols in the formula will be removed and replaced with actually values.</p>
<p><em>For example a list of symbols:</em></p>
<pre><code class="language-fsharp">let symbols = [SymbolToValue (&quot;base&quot;,100.0m);SymbolToValue (&quot;BASE&quot;,100.0m);SymbolToValue (&quot;Base&quot;,100.0m)]
</code></pre>
<h3 id="theorderofrulesofcalculation">The &quot;Order&quot; of rules of calculation</h3>
<p>Yeah, the very simple formula solver is basically enough for very simple formulas, but there are rules and we want to obey them.<br>
The strategy I want to use, is to reduce all higher operations than add and subtract to get a bunch of simple symbol/value pairs we put into our &quot;calculate&quot; method.</p>
<p><em>For example:</em></p>
<pre><code>1 + 2 * (3 + 4) ^ 3

// first the brackets (3+4) -&gt; 7
1 + 2 * 7 ^ 3

// now the power 7^3 -&gt; 343
1 + 2 * 343

// now the multiply 2*343 -&gt; 686
1 + 686

// we get the pairs
(+,1)
(+,686)

</code></pre>
<h4 id="thebrackets">The Brackets</h4>
<p>The Brackets are the first in line. So we need an Regex to extract all, what is inside a bracket and runs it to all other rules including the brackets rule. In the end, we want a list of symbols of plus and minus operation we can easily put into our &quot;calculate&quot; method, because in the end with only add and subtract operation we get to the point.</p>
<p><em>Listing of the function to resolve the Brackets:</em></p>
<pre><code class="language-fsharp">
        type BracketsFilter = Regex&lt; @&quot;\((?&lt;InsideBrackets&gt;[0-9.\+\-\*\/\^]*)\)&quot; &gt;

        let (|ContainsBrackets|NotContainsBrackets|) (str:string) =
            let is = str.Contains(&quot;(&quot;) || str.Contains(&quot;)&quot;)
            match is with
            |true -&gt; ContainsBrackets
            |false -&gt; NotContainsBrackets
            
        let rec resolveBrackets formula =
            let insideBracketsParts =
                formula            
                |&gt; BracketsFilter().TypedMatches
                |&gt; Seq.map (fun x -&gt; x.InsideBrackets.Value)
        
            let calculatedParts =
                insideBracketsParts
                |&gt; Seq.map (fun formulaPart -&gt; 
                    (formulaPart |&gt; sprintf &quot;(%s)&quot; ,formulaPart |&gt; resolvePower |&gt; resolveMultiply))
                |&gt; Seq.map (fun (part,multiresolved) -&gt; 
                    (part,multiresolved |&gt; splitFormula))
                |&gt; Seq.map (fun (part,split) -&gt; 
                    (part,split |&gt; calculate))

            let resolvedFormula =
                (formula,calculatedParts)
                ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                        let (formulaPart,resolvedPart) = calculatedPart                    
                        state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbol)
                    )
        
            match resolvedFormula with
            | ContainsBrackets -&gt; resolvedFormula |&gt; resolveBrackets
            | NotContainsBrackets -&gt; resolvedFormula

</code></pre>
<p>First I use an active pattern to check, if the formula contains some brackets. And yeah if could done this in a simple if then, but it want to use active pattern and it makes the function at the end more understandable.</p>
<p>The function is recursively and runs as long brackets are there.<br>
In the first step i extract all whats inside brackets with a Regex.<br>
The Regex take at first the inner brackets, that's because the function must run recursively.<br>
<em>here you see how the regex works:</em><br>
<img src="https://hardt.software/content/images/2018/05/20180520_regex_brackets_formula_resolver_recurrsively.png" alt="20180520_regex_brackets_formula_resolver_recurrsively"></p>
<p>Now I take all the extracted formula parts, whats inside a bracket and map this into a tuple of the formula part itself as string with brackets <em>sprintf &quot;(%s)&quot;</em>. That string do i need to replace it later the result of the calculation. The second part of the tuple contains the to add and subtract reducted partial formula. So I pipe the partial forumla to the <strong>&quot;resolvePower&quot;</strong> and the <strong>&quot;resolveMultiply&quot;</strong> functions.</p>
<p><em>Listing the calulatedParts function inside the resolveBrackets:</em></p>
<pre><code class="language-fsharp">            let calculatedParts =
                insideBracketsParts
                |&gt; Seq.map (fun formulaPart -&gt; 
                    (formulaPart |&gt; sprintf &quot;(%s)&quot; ,formulaPart |&gt; resolvePower |&gt; resolveMultiply))
                |&gt; Seq.map (fun (part,multiresolved) -&gt; 
                    (part,multiresolved |&gt; splitFormula))
                |&gt; Seq.map (fun (part,split) -&gt; 
                    (part,split |&gt; calculate))
</code></pre>
<p>Than I map this to the <strong>&quot;splitFormula&quot;</strong> function and than I map these to the <strong>&quot;calculate&quot;</strong> function.</p>
<p>The last mapping step is actually a folding step. So I replace the solved partial formulas with the result.</p>
<pre><code class="language-fsharp">
            let resolvedFormula =
                (formula,calculatedParts)
                ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                        let (formulaPart,resolvedPart) = calculatedPart                    
                        state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbol)
                    )
                    
</code></pre>
<p>I almost forget, there is a little helper function to replace a string only on the first hit. So i could avoid to replace parts multiple parts of the formula. Actually as I now think about it, maybe I cloud have used the normal replace function, because the resolved parts are the same. But now it is so as it is.</p>
<pre><code class="language-fsharp">
        let replaceStringOnlyFirstHit (search:string) replace (input:string) =
            let pos = input.IndexOf(search)
            if pos &lt; 0 then input
            else
                input.Substring(0,pos) + replace + input.[pos+search.Length..]

</code></pre>
<p>The last is only a fancy way to check if there are brackets left in the formula, so the function can be called recursively.</p>
<pre><code class="language-fsharp">
        match resolvedFormula with
            | ContainsBrackets -&gt; resolvedFormula |&gt; resolveBrackets
            | NotContainsBrackets -&gt; resolvedFormula

</code></pre>
<h4 id="power">Power</h4>
<p>The function has basically the same structure. It resolve the power operation.<br>
<em>Listing resolvePower function:</em></p>
<pre><code class="language-fsharp">
        type PowerFilter = Regex&lt; @&quot;(?&lt;Power&gt;[\+\-\*\/\^][0-9.]*[\^]{1}[\-]{0,1}[0-9.]*)&quot; &gt;

        let rec resolvePower formula =
            let formula = formula |&gt; tryAddLeadingPlus

            let powerParts =
                formula            
                |&gt; PowerFilter().TypedMatches
                |&gt; Seq.map (fun x -&gt; x.Power.Value)

            let calculatedParts =
                powerParts           
                |&gt; Seq.map (fun formulaPart -&gt; 
                    let leadingMathSymbol = formulaPart.[0]             
                    
                    (formulaPart, formulaPart.[1..] |&gt; splitFormula, leadingMathSymbol ))
                |&gt; Seq.map (fun (part,split,leadingMathSymbol) -&gt; (part,split |&gt; calculate,leadingMathSymbol))
        
            let resolvedFormula =
                (formula,calculatedParts)
                ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                        let (formulaPart,resolvedPart,leadingMathSymbol) = calculatedPart
                        state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbol |&gt; sprintf &quot;%c%s&quot; leadingMathSymbol)                    
                    )
        
            if resolvedFormula.Contains(&quot;^&quot;) then resolvedFormula |&gt; resolvePower
            else resolvedFormula

</code></pre>
<p>The little difference is, that i remember the leading math symbol in front of the power operation, so i can add the symbol afterward to the result. Also I did not run any of this towards another rolver function like in the <strong>&quot;resolveBrackets&quot;</strong>.</p>
<p>As i mentioned a formula like <strong>&quot;2^2^3&quot;</strong> results here in 64, the real result should according to wolfram alpha 256. This is because as I mentioned in the brackets part, the regex resolves from left to right. It is possible to change that behavior, but in our case it's overkill, because in the real world, nobody uses that to calculate a price. But maybe someone of you has an idea.</p>
<p>The both functions for brackets and power uses following little helper function:</p>
<pre><code class="language-fsharp">
        let decimalToSymbol (dec:decimal) =
            dec.ToString(usCulture)

</code></pre>
<h4 id="multiplyanddivide">Multiply and Divide</h4>
<p>The function has also the same structure as the both others. It resolve multiply and divide operations.</p>
<p><em>Listing of the resolveMultipy function:</em></p>
<pre><code class="language-fsharp">
        type MultiplyDivideFilter = Regex&lt; @&quot;(?&lt;MultiplyDivide&gt;[\+\-][0-9.]*[\*\/]{1}[\-]{0,1}[0-9.]*)&quot; &gt;

        let (|ContainsMultiplyDivideSymbol|NotContainsMultiplyDivideSymbol|) (str:string) =
            //let is = [&quot;*&quot;;&quot;/&quot;] |&gt; Seq.exists (fun symb -&gt; symb |&gt; str.Contains)
            let is = str.Contains(&quot;*&quot;) || str.Contains(&quot;/&quot;)
            match is with
            |true -&gt; ContainsMultiplyDivideSymbol
            |false -&gt; NotContainsMultiplyDivideSymbol

        let decimalToSymbolWithPrefix (dec:decimal) =
            let decStr = dec.ToString(usCulture)
            if dec &lt; 0.0m then decStr 
            else decStr |&gt; sprintf &quot;+%s&quot; 

        let rec resolveMultiply formula =
            let formula = formula |&gt; tryAddLeadingPlus

            let multiplyDivideParts =
                formula            
                |&gt; MultiplyDivideFilter().TypedMatches
                |&gt; Seq.map (fun x -&gt; x.MultiplyDivide.Value)

            let calculatedParts =
                multiplyDivideParts
                |&gt; Seq.map (fun formulaPart -&gt; (formulaPart, formulaPart |&gt; splitFormula))
                |&gt; Seq.map (fun (part,split) -&gt; (part,split |&gt; calculate))
        
            let resolvedFormula =
                (formula,calculatedParts)
                ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                        let (formulaPart,resolvedPart) = calculatedPart
                        state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbolWithPrefix)                    
                    )
        
            match resolvedFormula with
            | ContainsMultiplyDivideSymbol -&gt; resolvedFormula |&gt; resolveMultiply
            | NotContainsMultiplyDivideSymbol -&gt; resolvedFormula

</code></pre>
<p>There is the little active pattern function to have an fancy way to check if there are multiply or divide symbols in the formula (and a commented fancy way to check this more functional ... overkill I know, but I am learning).</p>
<p>The other helper function converts a decimal to a string with maybe a leading + if the result is positive. This i need, because maybe in front of the part I resolve is another number. So look, why i do that:</p>
<pre><code>1+2*3

// split +2*3
(+,2)
(*,3)

// calculate and replace

// without leading + the result would be 6
// so replace +2*3 with 6 i've got
16

// with leading + i got
1+6
</code></pre>
<p>I could have worked with the <strong>&quot;leadingMathSymbol&quot;</strong> from the power part, it also does the trick. But in that case the function to solve multiply and divide was written a little bit earlier than the resolve power function.<br>
So that's because i have this little helper.</p>
<p>In this function there will be alway added a + in front of the formula when there is no other math symbol in front. that's because in most cases the formula will not start with a symbol, and the function must split the formula into pairs and that will fail, when the first number has no leading math symbol.</p>
<h4 id="nowcomposetotheoneandonlycalculationfunction">Now compose to the one and only calculation function</h4>
<pre><code class="language-fsharp">
    let calculateFormula formula symbolToValueList =
        let valid = formula |&gt; formulaValidator symbolToValueList
        if (not valid) then
            Result.Error &quot;invalid formula&quot;
        else                        
            formula 
            |&gt; removeSpaces
            |&gt; replaceSymbols symbolToValueList
            |&gt; resolveBrackets
            |&gt; resolvePower
            |&gt; resolveMultiply                
            |&gt; splitFormula    
            |&gt; calculate
            |&gt; Result.Ok

</code></pre>
<p>As you see here. I have a also a validation function and some helpers like <strong>&quot;removeSpaces&quot;</strong> to get the formula well formed into my functions.</p>
<p>So that's all. Maybe a few words to the regex i used.</p>
<h4 id="mathpairregex">MathPairRegex</h4>
<pre><code>(?&lt;MathSymbol&gt;[\+\-\*\/\^])(?&lt;Number&gt;[\-]*[0-9.]*)
</code></pre>
<p>There are 2 groups the allowed math symbols are +,-,*,/,^ and the number. Allowed are only 0-9 and . and maybe a - in front</p>
<h4 id="bracketsfilterregex">BracketsFilter Regex</h4>
<pre><code>\((?&lt;InsideBrackets&gt;[0-9.\+\-\*\/\^]*)\)
</code></pre>
<p>The bracket filter is easy, give me all allowed characters inside a bracket.</p>
<h4 id="powerfilterregex">PowerFilter Regex</h4>
<pre><code>(?&lt;Power&gt;[\+\-\*\/\^][0-9.]*[\^]{1}[\-]{0,1}[0-9.]*)
</code></pre>
<p>The power filter gives you every math symbol before the first number, than the first number, the power symbol, maybe a minus and the second number.</p>
<h4 id="multiplydividefilterregex">MultiplyDivideFilter Regex</h4>
<pre><code>(?&lt;MultiplyDivide&gt;[\+\-][0-9.]*[\*\/]{1}[\-]{0,1}[0-9.]*)
</code></pre>
<p>The MultiplyDivideFilter takes a always a number with a leading + or - than at least a * or / and maybe a - and a value</p>
<h3 id="thatsall">That's all.</h3>
<p>I hope you read at least to the end. So this was my first journey to F# to solve a business rule.</p>
<p>I'll be please if you leave a comment or contact me for further discussions, help, ideas, critics or at least nice words.</p>
<p>oh. and the full listing you will find here, until i setup my github page.</p>
<p><em>Full Listing:</em></p>
<pre><code class="language-fsharp">
#r &quot;..[here the path to the regex type provider dll]..&quot;

open System.Text.RegularExpressions
open System.Linq
open System
open System.Globalization
open FSharp.Text.RegexProvider
    

    //Simple Parser for the price formula to be independent of an heavy weight dependency   


    type MathPairRegex = Regex&lt; @&quot;(?&lt;MathSymbol&gt;[\+\-\*\/\^])(?&lt;Number&gt;[\-]*[0-9.]*)&quot; &gt;
    type AllowedFormulaSymbolsRegex = Regex&lt; @&quot;[0-9.\+\-\*\/\^ \(\)]&quot; &gt;
    type IsMathSymbolRegex = Regex&lt; @&quot;[\+\-\*\/\^\(\)]&quot; &gt;

    type BracketsFilter = Regex&lt; @&quot;\((?&lt;InsideBrackets&gt;[0-9.\+\-\*\/\^]*)\)&quot; &gt;
    type PowerFilter = Regex&lt; @&quot;(?&lt;Power&gt;[\+\-\*\/\^][0-9.]*[\^]{1}[\-]{0,1}[0-9.]*)&quot; &gt;
    type MultiplyDivideFilter = Regex&lt; @&quot;(?&lt;MultiplyDivide&gt;[\+\-][0-9.]*[\*\/]{1}[\-]{0,1}[0-9.]*)&quot; &gt;

    let isMathSymbol (input:char) =
            IsMathSymbolRegex().IsMatch(input.ToString())

    type SymbolToValue = SymbolToValue of string * decimal

    let usCulture = new CultureInfo(&quot;en-us&quot;)    
    
    let formulaValidator symbolToValueList formula = 
        let clearedFormula:string = 
            (formula,symbolToValueList) 
            ||&gt; List.fold (fun (state:string) (item:SymbolToValue) -&gt;
                let (SymbolToValue (symbol,_)) = item
                state.Replace(symbol,&quot;&quot;)
                ) 
        let countMatches = 
            AllowedFormulaSymbolsRegex().Matches(clearedFormula).Count
        let onlyAllowedSymbols = (countMatches = clearedFormula.Length)
        if not onlyAllowedSymbols then false
        else
            // count the brackets
            let openBracketCount = clearedFormula.Count(fun x-&gt; x = '(')
            let closedBracketsCount = clearedFormula.Count( fun x -&gt; x = ')')
            openBracketCount = closedBracketsCount
        

    let replaceSymbols symbolToValueList formula =
        (formula,symbolToValueList) 
        ||&gt; List.fold (fun (state:string) (item:SymbolToValue) -&gt;
            let (SymbolToValue (symbol,value)) = item
            state.Replace(symbol,value.ToString(usCulture))
            ) 
    
    let removeSpaces (formula:string) = formula.Replace(&quot; &quot;,&quot;&quot;)

    let tryAddLeadingPlus (formula:string) =
            let isFirstCharMath = formula.[0] |&gt; isMathSymbol            
            if isFirstCharMath then formula 
            else &quot;+&quot; + formula

    let splitFormula (formula:string) = 
        formula        
        |&gt; tryAddLeadingPlus
        |&gt; MathPairRegex().TypedMatches        
        |&gt; Seq.map (fun i -&gt; (i.MathSymbol.Value,i.Number.Value)) 

    let (|ParsedDecimal|) value =
        Decimal.Parse(value,usCulture)

    let calculate (symbolValues:(string * string) seq) =
        (0.0m,symbolValues)
        ||&gt; Seq.fold (fun state item -&gt;
            match item with
            |(&quot;+&quot;,(ParsedDecimal value)) -&gt;                
                state + value
            |(&quot;-&quot;,(ParsedDecimal value)) -&gt;
                state - value
            |(&quot;*&quot;,(ParsedDecimal value)) -&gt;
                state * value
            |(&quot;/&quot;,(ParsedDecimal value)) -&gt;
                state / value
            |(&quot;^&quot;,(ParsedDecimal value)) -&gt;
                (decimal ((float state) ** (float value)))
            | _ -&gt; state
            
            )
    
    let (|ContainsMultiplyDivideSymbol|NotContainsMultiplyDivideSymbol|) (str:string) =
        //let is = [&quot;*&quot;;&quot;/&quot;] |&gt; Seq.exists (fun symb -&gt; symb |&gt; str.Contains)
        let is = str.Contains(&quot;*&quot;) || str.Contains(&quot;/&quot;)
        match is with
        |true -&gt; ContainsMultiplyDivideSymbol
        |false -&gt; NotContainsMultiplyDivideSymbol

    let decimalToSymbolWithPrefix (dec:decimal) =
        let decStr = dec.ToString(usCulture)
        if dec &lt; 0.0m then decStr 
        else decStr |&gt; sprintf &quot;+%s&quot;   

    let decimalToSymbol (dec:decimal) =
        dec.ToString(usCulture)
    
    let replaceStringOnlyFirstHit (search:string) replace (input:string) =
        let pos = input.IndexOf(search)
        if pos &lt; 0 then input
        else
            input.Substring(0,pos) + replace + input.[pos+search.Length..]



    // resolve Multiply
    let rec resolveMultiply formula =
        let formula = formula |&gt; tryAddLeadingPlus

        let multiplyDivideParts =
            formula            
            |&gt; MultiplyDivideFilter().TypedMatches
            |&gt; Seq.map (fun x -&gt; x.MultiplyDivide.Value)

        let calculatedParts =
            multiplyDivideParts
            |&gt; Seq.map (fun formulaPart -&gt; (formulaPart, formulaPart |&gt; splitFormula))
            |&gt; Seq.map (fun (part,split) -&gt; (part,split |&gt; calculate))
        
        let resolvedFormula =
            (formula,calculatedParts)
            ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                    let (formulaPart,resolvedPart) = calculatedPart
                    state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbolWithPrefix)                    
                )
        
        match resolvedFormula with
        | ContainsMultiplyDivideSymbol -&gt; resolvedFormula |&gt; resolveMultiply
        | NotContainsMultiplyDivideSymbol -&gt; resolvedFormula


    // resolve power
    let rec resolvePower formula =
        let formula = formula |&gt; tryAddLeadingPlus

        let powerParts =
            formula            
            |&gt; PowerFilter().TypedMatches
            |&gt; Seq.map (fun x -&gt; x.Power.Value)

        let calculatedParts =
            powerParts           
            |&gt; Seq.map (fun formulaPart -&gt; 
                let leadingMathSymbol = formulaPart |&gt; Seq.head                
                (formulaPart, formulaPart.[1..] |&gt; splitFormula, leadingMathSymbol ))
            |&gt; Seq.map (fun (part,split,leadingMathSymbol) -&gt; (part,split |&gt; calculate,leadingMathSymbol))
        
        let resolvedFormula =
            (formula,calculatedParts)
            ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                    let (formulaPart,resolvedPart,leadingMathSymbol) = calculatedPart
                    state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbol |&gt; sprintf &quot;%c%s&quot; leadingMathSymbol)                    
                )
        
        if resolvedFormula.Contains(&quot;^&quot;) then resolvedFormula |&gt; resolvePower
        else resolvedFormula
        
    let (|ContainsBrackets|NotContainsBrackets|) (str:string) =
        let is = str.Contains(&quot;(&quot;) || str.Contains(&quot;)&quot;)
        match is with
        |true -&gt; ContainsBrackets
        |false -&gt; NotContainsBrackets
            
    let rec resolveBrackets formula =
        let insideBracketsParts =
            formula            
            |&gt; BracketsFilter().TypedMatches
            |&gt; Seq.map (fun x -&gt; x.InsideBrackets.Value)
        
        let calculatedParts =
            insideBracketsParts
            |&gt; Seq.map (fun formulaPart -&gt; (formulaPart |&gt; sprintf &quot;(%s)&quot; ,formulaPart |&gt; resolvePower |&gt; resolveMultiply))
            |&gt; Seq.map (fun (part,multiresolved) -&gt; (part,multiresolved |&gt; splitFormula))
            |&gt; Seq.map (fun (part,split) -&gt; (part,split |&gt; calculate))

        let resolvedFormula =
            (formula,calculatedParts)
            ||&gt; Seq.fold (fun state calculatedPart -&gt; 
                    let (formulaPart,resolvedPart) = calculatedPart                    
                    state |&gt; replaceStringOnlyFirstHit formulaPart (resolvedPart |&gt; decimalToSymbol)
                )
        
        match resolvedFormula with
        | ContainsBrackets -&gt; resolvedFormula |&gt; resolveBrackets
        | NotContainsBrackets -&gt; resolvedFormula
           
        
    let calculateFormula formula symbolToValueList =
        let valid = formula |&gt; formulaValidator symbolToValueList
        if (not valid) then
            Result.Error &quot;invalid formula&quot;
        else                        
            formula 
            |&gt; removeSpaces
            |&gt; replaceSymbols symbolToValueList
            |&gt; resolveBrackets
            |&gt; resolvePower
            |&gt; resolveMultiply                
            |&gt; splitFormula    
            |&gt; calculate
            |&gt; Result.Ok


</code></pre>
</div>]]></content:encoded></item><item><title><![CDATA[F# - Why the hell i didn't recognize it before!]]></title><description><![CDATA[<div class="kg-card-markdown"><p>In the last 6 or 7 weeks I start to read and watch videos about the capabilities of F# and how it help me to write better code and better domain and business logics.</p>
<p>Thanks to Greg Young, the father of CQRS and developer of the EventStore, i want to</p></div>]]></description><link>https://hardt.software/f-why-didnt-i-recognize-it-before/</link><guid isPermaLink="false">5aeafc4d2d806413ecd1e9cc</guid><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Thu, 03 May 2018 14:25:24 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>In the last 6 or 7 weeks I start to read and watch videos about the capabilities of F# and how it help me to write better code and better domain and business logics.</p>
<p>Thanks to Greg Young, the father of CQRS and developer of the EventStore, i want to know about functional languages. One sentence, actually two, he said was:</p>
<blockquote>
<p>&quot;When we talk about Event Sourcing, current state is a left-fold of previous behaviors. Nothing new to Functional Programmers&quot;</p>
</blockquote>
<p>so in F# he meant:</p>
<pre><code class="language-fsharp">
let currentState =
    (initialState,sequenceOfEvents) ||&gt; Seq.fold applyEvent
    
</code></pre>
<p>So after that, I discovered talks of Scott Wlaschin and his site <a href="https://fsharpforfunandprofit.com/">fsharpforfunandprofit.com</a> and it is amazing what i can do with F# to model a domain and write code without heavy boilerplate like in C#.</p>
<p>Don't get me wrong, i love C#, but now i love F#, too.</p>
<p>So i start, likely for myself, to write, how i write code and modeling a business domain, here in my blog the next time.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Yak Shaving]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Hi there.</p>
<p>I had thought about the first post on my blog for quiet some time. Beside I am currently very busy in business, because a dead line is coming, but finally i found a small topic, I want to write about.</p>
<p>&quot;yak shaving&quot;. The thing is, I've</p></div>]]></description><link>https://hardt.software/yak-shaving/</link><guid isPermaLink="false">59fc140ca0728b02543178a1</guid><category><![CDATA[fun]]></category><category><![CDATA[yak shaving]]></category><dc:creator><![CDATA[Daniel Hardt]]></dc:creator><pubDate>Fri, 03 Nov 2017 07:22:45 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Hi there.</p>
<p>I had thought about the first post on my blog for quiet some time. Beside I am currently very busy in business, because a dead line is coming, but finally i found a small topic, I want to write about.</p>
<p>&quot;yak shaving&quot;. The thing is, I've never heard this term before. I've heard this term for the first, i think it was in a key note of the NDC-Conference with Scott Hanselman and he talked about, how someone shaves a yak.</p>
<p>You have to know, that I am a german citizen, so I am not familiar with the all the nice phrases you have. We have some of our own.</p>
<p>So here I want to say, that this term is awesome and it describes some of the tasks I am doing right now exactly as there are.</p>
<p>So nothing special on my first post, but this was some i want to talk about.</p>
<p>here is the current description of yak shaving:</p>
<blockquote>
<p>yak shaving describes the task, that you have to do, to complete another task, the is needed to complete another task, that is finally related to complete the task, that you have actually want to complete. An if somehow your boss come and looks for you, how far you come to complete the wanted task, your are standing in the room and shaving a yak and doing some other things from the perspective of your boss than to complete the task he ask for. (And now, explain this to him ...)</p>
</blockquote>
<p>Okay, maybe there are some other definitions out there. But i think that describes it well enough.</p>
</div>]]></content:encoded></item></channel></rss>