Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Monday, 6. December 2021


Santa and the container apps in the cloud

Filed under: Diverses — Steffen Forkmann at 20:30 Uhr

The post is a part of F# Advent Calendar 2021.

As every year Santa gets a lot of wishes from children all over the world. This year one of the elves heard about a new service in cloud called Azure Container Apps. The promise of this service is to have easy deployment with docker and automatic scaling of the instances. They even advertise “scale to zero”. Since Santa usually gets most of the wishes in December and almost none during the rest of the year, this sounds like a great way to save some bucks.

So during this evaluation phase Santa and the elves are building two container apps. One that works as a HTTP API and takes wishes via HTTP POST and one that processes wishes from an Azure ServiceBus queue.

So let’s take a look at Santa’s HTTP API – it’s a very simple dockerized Saturn app with just one endpoint. The code can be found at https://github.com/forki/XMasContainerApp/tree/main/src/HTTP.

It’s just taking the body of the POST request and put’s it into an Azure ServiceBus queue.

The receiver side is in the second container app (code):

So here Santa is listening in the ServiceBus queue and calling a handler for every message. So nothing fancy here.

Now Santa wonders how to get those things into the cloud. He already knows how to use docker, so he put a DOCKERFILE next to each container app, built the container images and pushed those to his container registry.

In the next step he wants to use farmer to orchestrate the deployment of those container apps. Farmer is a lovely DSL on top of Azure Resource Manager. Santa loves farmer, but unfortunately it doesn’t support Azure Container apps yet – but a pull request for this is just yet another christmas present, right?

Santa configured both container apps with specific auto scale rules. The HTTP endpoint scales based on the number of concurrent requests. Santa decides to have at least one replica running at all times. This ensures that traffic will always be handled without long cold starts.

For the second container app scaling is based on the number of messages in the ServiceBus queue. Most of the time there won’t be any messages at all – and since processing is happening async anyway, this app can actually scale down to zero. The rest of the farmer script can be found at https://github.com/forki/XMasContainerApp/blob/main/infrastructure/Program.fs.

After a bit of testing, Santa and the elves are very happy with this approach. The workflow is decoupled and individual components can scale based on the actual traffic. He plans to invest more energy into this approach once the dust settles after christmas.

Tags:

Monday, 23. February 2009


Using NaturalSpec to create a spec for C# projects (Updated 08.11.2009)

Filed under: F#,NaturalSpec — Steffen Forkmann at 18:07 Uhr

In my last two articles I gave an introduction in NaturalSpec and showed how to get started. This time I will show how we can use NaturalSpec to write automatically testable scenarios for C# projects.

Like the TDD principle “Write the tests first” we should write our spec first and use the “Red-Green-Refactor” method.

"Red" – Create a spec scenario that fails

At first I created a F# class library project called “Spec.CarSelling” and added project references to NaturalSpec.dll and nunit.framework.dll (see “Getting started” for further explanations).

Now I can write my first scenario:

// 1. define the module
module CarSpec
// 2. open the NaturalSpec namespace
open NaturalSpec // 3. open project namespace open CarSellingLib // 4. define a test context let Bert = new Dealer("Bert") // 5. create a method in BDD-style let selling_a_car_for amount (dealer:Dealer) = printMethod amount dealer.SellCar amount // 6. create a scenario [<Scenario>] let When_selling_a_car_for_30000_it_should_equal_my_DreamCar() = As Bert |> When selling_a_car_for 30000 |> It should equal (new Car(CarType.BMW, 200)) |> Verify

At this stage the scenario is ready but doesn’t compile. This means we are ready with the "Red"-stage.

"Green" – Make the test the pass

In order to get the test green we have to create a C# class library called CarSellingLib and define the enum CarType and the classes Dealer and Car. Sticking to the YAGNI-principle we implement only the minimum to get the spec green (and ToString()-members for the output functionality).

namespace CarSellingLib
{
    public enum CarType
    {
        BMW
    }
}

namespace CarSellingLib
{
    public class Car
    {
        public Car(CarType type, int horsePower)
        {
            Type = type;
            HorsePower = horsePower;
        }

        public CarType Type { get; set; }
        public int HorsePower { get; set; }

        public override string ToString()
        {
            return string.Format("{0} ({1} HP)", Type, HorsePower);
        }

        public override bool Equals(object obj)
        {
            var y = obj as Car;
            if(y == null) return false;
            return Type == y.Type && HorsePower == y.HorsePower;
        }
    }
}
using System;

namespace CarSellingLib
{
    public class Dealer
    {
        public Dealer(string name)
        {
            Name = name;
        }

        public string Name { get; set; }

        public Car SellCar(int amount)
        {
            return new Car(CarType.BMW, 200);
        }

        public override string ToString()
        {
            return Name;
        }
    }
}


When we add a project reference to our spec-project the UnitTests should pass and we have completed the "Green" step. (See "Getting started" if you don’t know how to run the spec.) Now we can add some more scenarios to our spec:

// 1. define the module 
module CarSpec
// 2. open NaturalSpec-Namespace
open NaturalSpec

// 3. open project namespace
open CarSellingLib

// 4. define a test context
let Bert = new Dealer("Bert")

// define reusable values
let DreamCar = new Car(CarType.BMW, 200)
let LameCar = new Car(CarType.Fiat, 45)

// 5. create a method in BDD-style
let selling_a_car_for amount (dealer:Dealer) =
  printMethod amount
  dealer.SellCar amount

// 6. create a scenario
[<Scenario>]
let When_selling_a_car_for_30000_it_should_equal_the_DreamCar() =
  As Bert
    |> When selling_a_car_for 30000
    |> It should equal DreamCar
    |> It shouldn't equal LameCar
    |> Verify      

[<Scenario>]
let When_selling_a_car_for_19000_it_should_equal_the_LameCar() =
  As Bert
    |> When selling_a_car_for 19000
    |> It should equal LameCar
    |> It shouldn't equal DreamCar
    |> Verify

// create a scenario that expects an error
[<Scenario>]
[<Fails_with "Need more money">]
let When_selling_a_car_for_1000_it_should_fail_with_Need_More_Money() =
  As Bert
    |> When selling_a_car_for 1000
    |> Verify

Now we are in the “Red”-Phase again.

"Refactor" – rearrange your code to eliminate duplication and follow patterns

After making the spec "Green" and doing some refactoring the project code could look like this:

namespace CarSellingLib
{
    public enum CarType
    {
        Fiat,
        BMW
    }
}

namespace CarSellingLib
{
    public class Car
    {
        public Car(CarType type, int horsePower)
        {
            Type = type;
            HorsePower = horsePower;
        }

        public CarType Type { get; set; }
        public int HorsePower { get; set; }

        # region ToString, Equals 

        public override string ToString()
        {
            return string.Format("{0} ({1} HP)", Type, HorsePower);
        }

        public override bool Equals(object obj)
        {
            var y = obj as Car;
            if(y == null) return false;
            return Type == y.Type && HorsePower == y.HorsePower;
        }

        #endregion
    }
}

using System;

namespace CarSellingLib
{
    public class Dealer
    {
        public Dealer(string name)
        {
            Name = name;
        }

        public string Name { get; set; }

        public Car SellCar(int amount)
        {
            if (amount > 20000)
                return new Car(CarType.BMW, 200);

            if (amount > 3000)
                return new Car(CarType.Fiat, 45);

            throw new Exception("Need more money");
        }

        public override string ToString()
        {
            return Name;
        }
    }
}

The spec output should look like the following:

Scenario: When selling a car for 1000 it should fail with Need More Money

– Should fail…
– As Bert
– When selling a car for 1000

Scenario: When selling a car for 19000 it should equal the LameCar

– As Bert
– When selling a car for 19000
=> It should equal Fiat (45 HP)
=> It should not equal BMW (200 HP)
==> OK

Scenario: When selling a car for 30000 it should equal my DreamCar

– As Bert
– When selling a car for 30000
=> It should equal BMW (200 HP)
==> OK

Scenario: When selling a car for 30000 it should equal the DreamCar

– As Bert
– When selling a car for 30000
=> It should equal BMW (200 HP)
=> It should not equal Fiat (45 HP)
>==> OK

4 passed, 0 failed, 0 skipped, took 1,81 seconds (NUnit 2.5).

Summary

I showed how we can use NaturalSpec for the Red-Green-Refactor process of C# projects and how easy it is to get a spec in natural language.

Tags: , , , , ,

Saturday, 6. October 2007


101 LINQ Samples

Filed under: .NET — Steffen Forkmann at 18:54 Uhr

LINQ (also Language Integrated Queries) ist momentan in aller (NET-)Munde. Wer sich mit der Syntax vertraut machen möchte kann auf MSDN 101 LINQ-Beispiele ansehen und durcharbeiten. Besonders die Samples die anonyme Typen verwenden, erzeugen eine gewisse Vorfreude bei mir.

Tags: ,

ReSharper 3.0 für Visual Studio 2005 im Test – Refactoring für Profis

Filed under: .NET,ASP.NET,C#,Firmen,Tools,Visual Studio — Steffen Forkmann at 12:03 Uhr

ReSharper ist ein Plugin der Firma JetBrains für Visual Studio, das sich speziell die Produktivitätssteigerung beim Entwickeln als Ziel gesetzt hat. Besonderes Augenmerk wird dabei auf die Refactoring-Unterstüzung gelegt, also auf das nachträgliche Umgestalten von Quellcode. JetBrains wirbt damit das “intelligenteste AddIn für Visual Studio” entwickelt zu haben – doch was kann ReSharper wirklich? 

(weiterlesen…)

Tags: , , , ,

Wednesday, 19. September 2007


Kurioses von der BASTA

Filed under: Lustiges,Veranstaltungen — Steffen Forkmann at 13:46 Uhr
Pleiten Pech und Pannen 

Bei meinem Vortrag über die Programmierung in Dynamics Nav hat mir mein Navision bei der Demo leider einen Streich gespielt und ist vollkommen unmotiviert abgeraucht. Da probiert man das Ganze zu Hause unzählige Male aus und genau in der Präsentation passiert der Unfall.

Aber heute habe ich erfahren, dass ich mich da noch glücklich schätzen kann. Torsten Weber ist heute in seiner Session über “Mobile Anwendungen mit dem .NET Compact Framework 2.0” das gesamte Vista abgestürzt. Das ist natürlich äußerst ärgerlich. Dafür hatte Torsten jedoch die mit Abstand schönsten Folien auf der BASTA.

[Noch schlimmer ist es jedoch, wenn man, wie es Dirk Primbs leider passiert ist, seine eigene KeyNote verpasst. Dafür ist jedoch Dariusz Parys eingesprungen.]

Abendprogramm

Das Abendprogramm gestern bestand in einer Session, in der jeder BASTA-Teilnehmer die Möglichkeit hatte 5 Minuten auf der Bühne über ein Thema seiner Wahl referieren. Dabei konnten die Zuhörer den Redner auch abwählen und selbst das Mikrofon übernehmen.  Als Anreiz konnte man neben einem BASTA-Schlüßelbändchen (Trostpreis) auch attraktive Sachpreise gewinnen. Das Highlight war jedoch als ein Oracle-Mitarbeiter (O-Ton “Orahkäl”) 5 min. lang versuchte Leute zu finden, die im nächsten Jahr auch mal einen Oracle-Vortrag auf der BASTA hören wollen. Als Preis loste er sich dann ein SQL-Server Buch. 😉 Nicht zu fassen.

Aber es kam noch besser: Im Anschluss an den Oracle-Vertreter wurde Masoud Kamali auf die Bühne gebeten, seines Zeichens Gründer und Geschäftsführer des Software & Support Verlages. Er sollte in 5min. die Gründunggeschichte und die weitere Zukunft (O-Ton: “Wir schlagen Google!”) des Verlages zu erklären. Der Software & Support Verlag ist ja auch Veranstalter der BASTA und der Hauptpreis des Abends (Kostenlose Teilnahme an der BASTA 2008) wurde nun genau von deren Chef gezogen – welch eine Ironie in 10 Minuten.

Das Ticket wird nun übrigens bei Ebay versteigert und der Erlös geht an Ärzte ohne Grenzen.

Am zweiten Abend wurde dann übrigens Poker gespielt – leider ohne persönliche Einsätze, so dass eigentlich mit jeder Hand gespielt (und verloren) wurde.

Pokern auf der BASTA

Speaker-Shirts

Die Speaker laufen auf der BASTA alle mit so tollen schwarzen Polo-Shirts rum. Wie ich jedoch erfahren habe, sollte ich meins immer schön anlassen. Das Shirt von Michael Willers  ist offenbar so begehrt, dass es gestern geklaut wurde. 😉

Interessant ist in dem Zusammenhang auch der Blog-Eintrag von Benjamin Gopp 😉

Auf der Rückfahrt gab es dann noch folgendes Highlight:

Bielefeld

Tags: , , , , , , ,

Monday, 28. May 2007


Bericht zur Student Technology Conference 2007

Filed under: .NET,Veranstaltungen — Steffen Forkmann at 16:46 Uhr

Vom 21. bis 22. Mai 2007 fand die STC 2007 im Landschaftspark Duisburg statt. Da ich bereits 2005 auf der STC in Mainz war, wollte ich auch unbedingt dieses Jahr hin. Und ich kann gleich vorweg nehmen: es hat viel Spaß gemacht – nicht zuletzt da wir diesmal eine 9er Gruppe gebildet haben.

Da die Keynote am Montag (21.5.2007) bereits um 10 gehalten werden sollte, hatten wir uns entschlossen einen Tag früher anzureisen und in der Jugendherberge Duisburg Meiderich zu übernachten. Wie sich heraus stellte war die Jugendherberge nur 300 Meter vom Tagungsgelände entfernt, so dass wir uns nach dem langen Playstation-Turnier ohne Probleme bei der STC anmelden konnten.

(weiterlesen…)

Tags: , , , ,

Thursday, 24. May 2007


Microsoft macht Partner fit für Web 2.0

Filed under: .NET,ASP.NET,Diverses,Firmen,Veranstaltungen,Visual Studio,WPF — Jens Hesse at 23:02 Uhr

Durch die sogenannte “LiftOff Initiative” sollen Microsoft Partner in einem Trainingsprogramm an die Technologien rund ums Web 2.0 herangeführt werden. Schwerpunkt der Trainingsmaßnahme ist die Integration der Microsoft Webtechnologien (WPF/E, ASP.NET, AJAX), Web Services und Map Point, sowie Workflow Management.

(weiterlesen…)

Tags: , , , , , ,

Friday, 18. May 2007


WordPress Anti-Spam-Plugin "Akismet" für .NET

Filed under: .NET,Blogs,Tools — Steffen Forkmann at 19:54 Uhr

Aufgrund eines Blogeintrags von Damir Tomicic und den guten Erfahrungen die ich mit Akismet gemacht habe, möchte ich an dieser Stelle mal auf ein .NET Akismet-API ausmerksam machen. Arne Brachhold hat den Zugriff auf den Webservice von Akismet als .NET-Klassenbibliothek gekapselt und bietet diese .dll frei zum Download an. Man kann diese dann zum Beispiel in ASP.NET Foren oder Blogs einbauen.

Laut der Akismet-Homepage sind übrigens 95% aller Kommentareinträge Spam – auf meinem Blog wurden bisher 16.138 Kommentare als Spam identifiziert.

Nachtrag: Es gibt das Projekt auch auf CodePlex.

Tags: , ,

Wednesday, 2. May 2007


GhostDoc 2.0 released

Filed under: .NET,Tools,Visual Studio — Steffen Forkmann at 8:24 Uhr

Das bekannte Dokumentations-Plugin für Visual Studio geht in die zweite Runde. Hier die neuen GhostDoc-Features im Überblick:

  • Läuft auf Windows Vista
  • Läuft unter Visual Studio Orcas (Beta 1)
  • Bessere Unterstützung der Generics und anderen neuen Sprachelementen
  • Weitere Informationen gibt es im GhostDoc-Blog.

    Tags: , ,

    Tuesday, 24. April 2007


    ICE2007 in Lingen – Intelligent Communities for Europe

    Filed under: .NET,Veranstaltungen — Steffen Forkmann at 8:41 Uhr

    Bereits im letzten Jahr war ich mit meinem Kollegen Jens Hesse auf der ICE in Lingen. Dieses Jahr findet die kostenfreie Community-Tagung am 15. September statt. Die Anmeldung zur \\ice:2007 ist ab dem 01.05.07 möglich und die Teilnehmerzahl ist auf 250 begrenzt.

    ICE 2006 in Lingen

    Weitere Informationen:

    ice2007

    Warning: Creating default object from empty value in /www/htdocs/w007928a/blog/wp-content/plugins/wp-referencesmap/GoogleMapsWrapper.php on line 55


    Nachtrag: Jetzt ist auch ein Trailer zur ICE 2007 erschienen.

    Tags: , , , ,