Event Storming with Specifications by Example

Event Storming is a technique defined and refined by Alberto Brandolini (@ziobrando). I fully agree the statement about this method, Event Storming is for now “The smartest approach to collaboration beyond silo boundaries”

I don’t want to explain what Event Storming is, the concept is present in the IT world for a few years already and there are a lot of articles or videos explaining the basics. What I want to emphasize is WHY do we need to learn and apply this technique:

The knowledge of the product experts may differ from the assumption of the developers
KanDDDinsky 2018 – Kenny Baas-Schwegler

On the 18-19.10.2018 I had the opportunity to not only hear a great talk about Event Storming but also to be part of a 2 hours long hands-on session, all this powered by Kandddinsky (for me the best conference I visited this year) and by @kenny_baas (and @use case driven and @brunoboucard). In the last few years I participated on a few Event Storming sessions, mostly on community events, twice at cleverbridge but this time it was different. Maybe ES is like Unit Testing, you have to exercise and reflect about what went well and what must be improved. Anyway this time I learned and observed a few rules and principles new for me and their effects on the outcome. This is what I want to share here.

  1. You need a facilitator.
    Both ES sessions I was part at cleverbridge have ended with frustration. All participants were willing to try it out but we had nobody to keep the chaos under control. Because as Kenny said “There will be chaos, this is guaranteed.” But this is OK, we – devs, product owners, sales people, etc. – have to learn fast to understand each other without learning the job of the “other party” or writing a glossary (I tried that already and didn’t helped 😐 ). Also we need somebody being able to feel and steer the dynamics in the room.


    The tweets were written during a discussion about who could be a good facilitator. You can read the whole thread on Twitter if you like. Another good article summarizing the first impressions of @mathiasverraes as facilitator is this one.

  2. Explain AND visualize the rules beforehand.
    I skip for now the basics like the necessity of a very long free wall and that the events should visualize the business process evolving in time.
    This are the additional rules I learned in the hands-on session:

      1. no dev-talk! The developer is per se a species able to transform EVERYTHING in patterns and techniques and tables and columns and this ability is not helpful if one wants to know if we can solve a problem together. By using dev-speech the discussion will be driven to the technical “solvability” based on the current technical constraints like architecture. With ES we want to create or deepen our ubiquitous language , and this surely not includes the word “Message Bus”  😉
      2. Every discussion should happen on the board. There will be a lot of discussions and we tend to talk a lot about opinions and feelings. This won’t happen if we keep discussing about the business processes and events which are visualized in front of us – on the board.
      3. No discussions regarding persons not in the room. Discussing about what we think other people would mind are not productive and cannot lead to real results. Do not waste time with it, time is too short anyway.
      4. Open questions occurring during the storming should not be discussed (see the point above) but marked prominently with a red sticky. Do not waste time
      5. Do not discuss about everything, look for the money! The most important goal is to generate benefit and not to create the most beautiful design!

Tips for the Storming:

  • “one person, one sharpie, one set of stickies”: everybody has important things to say, nobody should stay away from the board and the discussions.
  • start with describing the business process, business rules, eventual consistent business decisions aka policies, other constraints you – or the product owner whom the business “belongs” – would like to model, and write the most important information somewhere visible for everybody.
  • explain how ES works: every business relevant event should be placed on a time line and should be formulated in the past tense. Business relevant is everything somebody (Kibana is not a person, sorry 😉 ) would like know about.
  • explain the rules and the legend (you need a color legend to be able to read the results later).
  • give the participants time (we had 15 minutes) to write every business event they think it is important to know about on orange stickies. Also write the business rules (the wide dark red ones) and the product decisions (the wide pink ones) on stickies and put them there where they are applied. The rules before the event, the policies after one event happened.
  • start putting the stickies on the wall, throw away the duplicates, discuss and maybe reformulate the rest. After you are done try to tell the story based on what you can read on the wand. After this read the stickies from the end to the start. With these methods you should be able to discover if you have gaps or used wrong assumptions by modelling the process you wanted to describe.
  • mark known processes (like “manual process”) with the same stickies as the policies and do not waste time discussing it further.
  • start to discuss the open questions. Almost always there are different ways to answer this questions and if you cannot decide in a few seconds than postpone it. But as default: decide to create the event and measure how often happens so that later on you can make the right decision!
    Event Storming – measure now, decide later


    Another good article for this topic is this one from @thinkb4coding

At this point we could have continued with the process to find aggregates and bounded contexts but we didn’t. Instead we switched the methodology to Specifications by Example – in my opinion a really good idea!

Specifications
Event Storming enhanced with Specifications by Example

We prioritized the rules and policies and for the most important ones we defined examples – just like we are doing it if we discuss a feature and try to find the algorithm.

Example: in our ticket reservation business we had a rule saying “no overbooking, one ticket per seat”. In order to find the algorithm we defined different examples:

  • 4 tickets should be reserved and there are 5 tickets left
  • 4 tickets should be reserved and there are 3 tickets left
  • 4 tickets should be reserved and all tickets are already reserved.

With this last step we can verify if our ideas and assumptions will work out and we can gain even more insights about the business rules and business policies we defined – and all this not as developer writing if-else blocks but together with the other stake holders. At the same time the non-techie people would understand in the future what impact these rules and decisions have on the product we build together. The side-effect having the specifications already defined is also a great benefit as these are the acceptance tests which will be built by the developer and read and used by the product owner.

More about the example and the results can you read on the blog of Kenny Baas-Schwegler.

I hope I covered everything and have succeeded to reproduce the most important learning of the 2 days ( I tend to oversee things thinking “it is obvious”). If not: feel free to ask, I will be happy to answer 🙂

Happy Storming!

Update: we had our first event storming and it was good!

Unfortunately we didn’t get to define the examples (not enough time). Most of the rules described above were accepted really well (explain the rules, create a legend for the stickies, flag everything out of scope as Open Question). Where I as facilitator need more training is by keeping the discussion ON the board and not beside. I have also a few new takeaways:

  • the PO describes his feature and gives answers, but he doesn’t write stickies. The main goal ist to share his vision. This means, he should test us if we understood the same vision. As bonus he should complete his understanding of the feature trough the questions which appear during the storming.
  • one color means one action/meaning. We had policies and processes on the same red stickies and this was misleading.
  • if you have a really complex domain
    (like e-commerce for SaaS products in our case) or really complex features start with one happy path example. Define this example and create the event “stream” with this example. At the end you should still add the other, not so happy-path examples.

Kollegen-Bashing – Überraschung, es hilft nicht!

Bei allen Konferenzen, die meinen Kollegen und ich besuchen, poppt frĂŒher oder spĂ€ter das Thema Team-Kultur auf, als Grund von vielen/allen Problemen. Wenn wir erzĂ€hlen, wie wir arbeiten, landen wir unausweichlich bei der Aussage “eine selbstorganisierte crossfunktionale Organisation ohne einen Chef, der DAS Sagen hat, ist naiv und nicht realistisch“. “Ihr habt irgendwo sicher einen Chef, ihr wisst es nur nicht!” war eine der abgefahrensten Antworten, die wir unlĂ€ngst gehört haben, nur weil der GesprĂ€chspartner nicht in der Lage war, dieses Bild zu verarbeiten: 5 Selbstorganisierte Teams, ohne Chefs, ohne CTO, ohne Projektmanager, ohne irgendwelche von außen eingekippte Regeln und Anforderungen, ohne Deadlines denen wir widerspruchslos unterliegen wĂŒrden. DafĂŒr aber mit selbst auferlegten Deadlines, mit Budgets, mit Freiheiten und Verantwortung gleichermaßen.

Ich spreche jetzt hier nicht vom Gesetz und von der Papierform: natĂŒrlich haben wir in der Firma einen CTO, einen Head of Development, einen CFO, sie entscheiden nur nicht wann, was und wie wir etwas tun. Sie definieren die Rahmen, in der die GeschĂ€ftsleitung in das Produkt/Vorhaben investiert, aber den Rest tun wir: POs und Scrum Master und Entwickler, gemeinsam.

Wir arbeiten seit mehr als einem Jahr in dieser Konstellation und wir können noch 6 Monate Vorlaufzeit dazurechnen, bis wir in der Lage waren, dieses Projekt auf Basis von Conways-Law zu starten.

“Organizations which design systems [
] are constrained to produce designs which are copies of the communication structures of these organizations.” [Wikipedia]

In Umkehrschluss (und freie Übersetzung) heißt das “wie deine Organisation ist, so wird auch dein Produkt, dein Code strukturiert sein”. Wir haben also an unserer Organisation gearbeitet. Das Ziel war, ein verantwortungsvolles Team aufzubauen, das frei zum TrĂ€umen ist, um ein neues, großartiges Produkt zu bauen, ohne auferlegten Fesseln.

Wir haben jetzt dieses Team, wir leben jetzt diesen Traum – der natĂŒrlich auch Schatten hat, das Leben ist schließlich kein Ponyhof :). Der Unterschied ist: es sind unsere Probleme und wir drĂŒcken uns nicht davor, wir lösen sie zusammen.

Bevor ihr sagt “das ist ein GlĂŒcksfall, passiert normalerweise nicht” wĂŒrde ich widersprechen. Bei uns ist es auch nicht nur einfach so passiert, wir haben (ungefĂ€hr 6 Monate) daran gearbeitet, und tun es weiterhin kontinuierlich. Der Clou, der SchlĂŒssel zu dieser Organisation ist nĂ€mlich eine offene Feedback-Kultur.

Was soll das heißen, wie haben wir das bei uns erreicht?

  • Wir haben gelernt, Feedback zu geben und zu nehmen – ja, das ist nicht so einfach. Das sind die Regeln
    • Alle Aussagen sind Subjektiv: “Gestern als ich Review gemacht habe, habe ich das und das gesehen. Das finde ich aus folgenden GrĂŒnden nicht gut genug/gefĂ€hrlich. Ich könnte mir vorstellen, dass so oder so es uns schneller zum Ziel bringen könnte.” Ihr merkt: niemals DU sagen, alles in Ich-Form, ohne vorgefertigten Meinungen oder Annahmen.
    • Alle Aussagen mit konkreten Beispielen. Aussagen mit “ich glaube, habe das GefĂŒhl, etc.” sind Meinungen und keine Tatsachen. Man muss ein Beispiel finden sonst ist das Feedback nicht “zulĂ€ssig”
    • Das Feedback wird immer konstruktiv formuliert. Es hilft nicht zu sagen, was schlecht ist, es ist viel wichtiger zu sagen woran man arbeiten sollte: “Ich weiß aus eigener Erfahrung, dass Pair-Programming in solchen FĂ€llen sehr hilfreich ist” z.B.
    • Derjenige, die Feedback bekommt, muss es anhören ohne sich zu recht fertigen. Sie muss sich selber entscheiden, was sie mit dem Feedback macht. Jeder, der sich verbessern möchte, wird versuchen, dieses Feedback zu Herzen zu nehmen und an sich zu arbeiten. Das muss man nicht vorschreiben!
  • One-and-Ones: das sind Feedback-Runden zwischen 2 Personen in einem Team, am Anfang mit Scrum Master, solange die Leute sich an die Formulierung gewöhnt haben (wir haben am Anfang die ganze Idee ausgelacht) und spĂ€ter dann nur noch die Paare. Jedes mal nur in eine Richtung (nur der eine bekommt Feedback) und z.B. eine Woche spĂ€ter in die andere Richtung. Das Ergebnis ist, das wir inzwischen keine Termine mehr haben, wir machen das automatisch, jedes Mal, wenn etwas zu “Feedbacken” ist.
  • Team-Feedback: ist die letzte Stufe, lĂ€uft nach den gleichen regeln. Wird nicht nur zwischen Teams sondern auch zwischen Gruppen/Gilden gehalten, wie POs oder Architektur-Owner.

Das war’s. Ich habe seit ĂŒber einem Jahr nicht mehr SĂ€tze gehört, wie “die Teppen von dem anderen Team waren, die alles verbockt haben” oder “Die kriegen es ja sowieso nicht hin” oder “Was kĂŒmmert es mich, sie haben ja den Fehler eingecheckt” Und diese ArbeitsatmosphĂ€re verleiht FlĂŒgel! (sorry fĂŒr die copy-right-Verletzung 😉 )

10 Jahre Open Space – meine Retrospektive

Workshop-Tag:

Seit ein paar Jahren gibt es die Möglichkeit, den Open Space um ein Tag Workshop zu erweitern – wenn einem die zwei Tage Nerdtalk nicht reichen  😉

Ich habe mich diesmal fĂŒr Tensorflow: Programming Neural Networks mit Sören Stelzer entschieden – und es war großartig. Obwohl ein sehr schwieriges Thema (das Wort Voodoo ist öfter gefallen), ich weiß jetzt genug ĂŒber Machine Learning und Neuronale Netze, um mit dem Thema gut starten zu können. Ich formuliere es mal so: ich weiß jetzt, was ich weiß und vor allem, was ich nicht weiß und wie wir weiter machen mĂŒssen. Und mehr kann man von einem Workshop nicht erwarten. ZusĂ€tzlich finde ich, dass Sören eine sehr große Bereicherung fĂŒr unsere Community ist, die sich genauso weiterentwickeln muss, wie die IT-Welt da draußen. Vielen Dank fĂŒr dein Engagement!

Eigentlich ein fetten Dank an alle Trainer, die sich bei Community-Events engagieren!!

Erkenntnisse der nĂ€chsten 48 Stunden – geclustert:

Agile datengetriebene Entwicklung – war meine eigene Session (das heißt, ich habe das Thema vorgeschlagen, war Themen-Owner aber das war’s dann auch mit den Pflichten).

Ich wollte Tipps und Ideen dazu hören, wie man seine Arbeit nach scrum organisieren kann wenn man Themen beackert, wie Reporting, wo die Features auf große Menge Daten basieren. Es ist eine Sache, ein Testsetup fĂŒr 2 möglichen Situationen zu schreiben und es ist eine ganz andere, die vielfalt der Situationen in Reporting zu beschreiben.

Take-aways:

  • wir werden damit leben mĂŒssen, dass unsere Features, Tests, Erwartungen eventual consistent sind  😀 Wichtig ist, dass wir Annahmen treffen, die wir fĂŒr den Anfang als “die Wahrheit” betrachten.
  • User labs beauftragen.
  • Measurements weit vor ihre Auswertung einzubauen ist ok, bricht nicht mit dem Konzept “Jedes Feature muss Business Value haben” – auch wenn der echte Business Value erst in 2 Jahren auswertbar ist.
  • Aha-Effekt: In der Welt von Business Teams gibt es keine Fachabteilung. Ich bin in dem Reporting-Team ergo ich bin die Fachabteilung. (finde ich gut, hĂ€ĂŸliches Wort  😎 )

Stolperfallen mit React

  • unser Internationalisierungskonzept ist richtig (Texte aufteilen nach Modulen/Bereiche/o.Ă€., ein common Bereich, alles via API in den State laden)
  • Package-Empfehlung: react-intl
  • das Thema so frĂŒh, wie möglich berĂŒcksichtigen, spĂ€ter kann es richtig weh tun.
  • DevTool-Empfehlung: https://github.com/crysislinux/chrome-react-perf um die Performance der einzelnen React-Componenten zu sehen.
  • (es)Linting Empfehlung um zirkulĂ€re Referenzen zu vermeiden:  “import/no-internal-modules” (Danke @kjiellski)

Wann kann Scrum funktionieren

  • wenn die Möglichkeit besteht, auf Feedback zu reagieren, sprich die Entwickler sind keine Resourcen sondern kreative Menschen.
  • das Team, in dem ich die Ehre habe, unser Produkt mitzugestallten, und @cleverbridge ist fĂŒhrend was agiles Arbeiten betrifft.

Menschen

  • man kann bei Trinkspielen mitmachen, ohne zu trinken
  • nachts trĂ€umen, dass der Partner einen enttĂ€uscht hat und danach den ganzen Tag sauer auf ihn sein, ist eine Frauen-Sache (bestĂ€tigt von @AHirschmueller und @timur_zanagar) 😀

Nachtrag: fast vergessen, dass

  • wir dank @agross eine super wertvolle Session ĂŒber dotfiles hatten
  • DDD wird gerade durch Zertifizierung kaputt gemacht, Serverless durch Hype
  • mit der Session von @a_mirmohammadi ĂŒber/zu den Anonymen Abnehmer ist der @devopenspace eindeutig in die Kategorie “es gibt nichts, was nicht geht” angekommen

Graph databases

My second day at the Spartakiade was dedicated to the subject of graph databases.

In computing, a graph database is a database that uses graph structures for semantic queries with nodes, edges, and properties to represent and store data. A graph database is any storage system that provides index-free adjacency. This means that every element contains a direct pointer to its adjacent elements and no index lookups are necessary. General graph databases that can store any graph are distinct from specialized graph databases such as triplestores and network databases. (source: Wikipedia)

The workshop was led by Stephan (@Piratevsninja) – thank you very much! – and we used Neo4j, the most popular open source graph database. After this day of dive-in I can say I can start to create my first graph database application without asking myself all the time what the hell am I doing 🙂

Also: what is a graph database?

On a very high level we can split the databases into two types: RDBMS and NoSQL. In other words: into relational and nonrelational storages.

NoSQL databases – called by Martin Fowler Not Only SQL have the main focus on the data model and not on the relations between the data. Mostly there isn’t any relation between the entities. They can be differentiated based on the data model they use. Here some examples: Key-value storages (Redis, CouchDB, etc.), Document DBs (Lotus Notes, MongoDB, etc.), Column based DBs (Cassandra, HBase, etc.).

Relational databases (RDBMS) store the data denormalized and define the relations between the data types (also ALL the entries of one type). I don’t think I have to give examples for our plain old databases: if you can join and distinct data you are in the world of relational databases.

Graph databases combine both worlds: they are relational databases with the main focus on the relations between the data (not between the data model) – or like Stephan formulated it: they put data in the context of relationships.

Nodes and relations
Emil knows Ian (source: neo4j.com)

How you define the content ?

A graph database contains nodes (instances like “Emil” and “Ian”) and relations between these nodes (“knows”). One node is defined through some properties and can be grouped through labels. They often have aliases to be easier to work with them:

Emil:Person {name:"Emil", age:"20"}, Ian:Person {name:"Ian"}

One relation is defined through a name, the nodes it connects and the direction of this connection. Relations can also have properties but they should be very carefully chosen. They must describe the relation and not the nodes.

(Emil)-[:KNOWS {certainty:100}]->(Ian)

Now is clear to see what is the difference between a “plain” relational and a graph database: for the former you care always about the data. For the latter the data means nothing without the relation to some other data.

Movies and actors

 

Fine, I can set actors in relations. So what?

The most important point is: think around a corner. The fact that I can report that Ian knows Emil and Johann knows Emil too can be interesting but I don’t think there are any new business ideas in the domain of social connections which weren’t evaluated yet. What about the information that only 20% of the Swedish tourists who visit Germany and are between 18 and 25 do not speak German? This is surely a VERY interesting to know if you sell German dictionaries in the near of Universities…
I just invented this idea – I have no idea how many Swedish guys between 18 and 25 are speaking German 😉 – but this is what I mean with think around a corner!

What else remains to do?

After giving a good thought to the design: the relations and the connected data – like ids and oder characteristics but only if they are must-have – there are only a few things to do. Neo4j just like all the other graph databases have some kind of API to create, insert, update and query data. You only have to save the data across your application and create a UI (or use the one from Neo4j which is one of the coolest UI I ever saw) to create reports. Put this reports in front of the business analyst and you are done!

Create class from JSON

Ich habe vor einem Jahr bei einer katastrophalen MSFT-Veranstaltung ĂŒber ein super Feature in VS2012 erfahren, das ich – brownfield-bedingt – noch nie ausprobieren konnte. Heute hat es mir allerdings mindestens eine halbe Stunde Arbeit und eine große Menge Frust erspart!

Das Feature ist sehr schnell erklĂ€rt: wenn man ein Objekt, das als JSON oder XML serialisiert vorliegt – also einen string 😉 – in Zwischenspeicher hat, dann kann man das direkt als Klassenmodel abspeichern. Tatata..Fertig 🙂
Edit/Paste Special

Templating mit Razor aber ohne MVC

Ich habe unlĂ€ngst nach einer Möglichkeit gesucht, Seiten schnell und effektiv zu generieren, sowohl fĂŒr Web als auch fĂŒr E-Mails als Background-Jobs. Ein Kollege hat mich auf @razorengine aufmerksam gemacht und diese Templating Engine scheint alles zu bieten, was ich gesucht habe.

A templating engine built upon Microsoft’s Razor parsing technology. The RazorEngine allows you to use Razor syntax to build robust templates. Currently we have integrated the vanilla Html + Code support, but we hope to support other markup languages in future.

Die Installation ist so einfach wie möglich:

//mit NuGet:
Install-Package RazorEngine

Man muss danach nur noch die RazorEngine.dll und System.Web.Razor.dll referenzieren und das war’s.

 

Das Generieren von Seiten kann entweder direkt oder mit vorkompilierten Templates erfolgen:

[Test]
public void PageCanBeParsed()
{
   const string template = "Hello @Model.Name! Welcome to Razor!";
   var result = Razor.Parse(template, new {Name = "World"});

   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}
//unterstĂŒtzt anonyme Klassen
[Test]
public void PageCanBeParsedWithCompiledTemplate()
{
   const string template = "Hello @Model.Name! Welcome to Razor!";
   Razor.CompileWithAnonymous(template, "world");
   var result = Razor.Run(new {Name = "World"}, "world");

   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}
//oder konkrete Typen
[Test]
public void TemplateIsCompiledWithModelType()
{
   const string template = "Hello @Model.Name! Welcome to Razor!";
   var testModel = new TestModel{ Name = "World" };
   Razor.Compile( template, typeof(TestModel), "world2" );
   var result = Razor.Run(testModel, "world2");
   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}

public class TestModel { public string Name; }

Um ehrlich zu sein, ich habe noch keinen Grund gefunden, warum man nicht die vorkompilierte Variante nutzen soll. In diesem Fall wird das Template EIN MAL kompiliert und in Cache abgelegt. Ein Vergleichs- und Stresstest, in dem ich ein halbwegs komplexes Template 500-mal mit Razor.Parse bzw. mit Razor.Compile + Razor.Run aufgerufen habe, hat folgendes geliefert:

   Parse: 03:35.97 min
   Compile+Run: 00:00.63 min

Ich glaube, damit ist alles gesagt. Es sei denn, eine Zeile weniger gilt auch als Argument 🙄

 

RazorEngine unterstĂŒzt fast alles, was Microsoft’s Razor in Views anbietet, wie zum Beispiel Helper-Methoden, Model-Definitionen direkt im Template oder partielle Views:

[Test]
public void EngineSupportsInlineHelper()
{
   const string template = @"@helper MyMethod(string name) {Hello @name}@MyMethod(Model.Name)! Welcome to Razor!";
   var testModel = new TestModel{ Name = "World" };
   var result = Razor.Parse(template, testModel);
   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}

[Test]
public void EngineSupportsInheritsCommand()
{
   const string template = @"@inherits RazorEngine.Templating.TemplateBase
@helper MyMethod(string name) {Hello @name}@MyMethod(Model.Name)! Welcome to Razor!";
   var testModel = new TestModel{ Name = "World" };
   Razor.Compile(template, typeof(TestModel),"testModel");
   var result = Razor.Run(testModel, "testModel");

   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}

[Test]
public void EngineSupportsSubtemplating()
{
    const string masterTemplate = "You are on www.yellow-brick-code.org!";
    Razor.Compile(masterTemplate, typeof(TestModel), "master");

    const string contentView = @"@inherits RazorEngine.Templating.TemplateBase
@helper MyMethod(string name) {Hello @name}@MyMethod(Model.Name)! Welcome to Razor!";
    var testModel = new TestModel{ Name = "World" };

    const string template = contentView + " @Include(\"master\")";

    Razor.Compile(template, typeof(TestModel), "testModelMaster");
    var result = Razor.Run(testModel, "testModelMaster");
    Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor! You are on www.yellow-brick-code.org!"));
}

Und nun sind wir soweit, das Ganze im Web zu testen.

 

Die Engine funktioniert so, dass sie zur Laufzeit aus dem Template eine dll mit einem Zufallsnamen erstellt. Also wenn man die Engine im Web nutzen will, mĂŒssen noch ein paar Dinge getan werden:

  1. RazorEngine.Web.dll referenzieren
  2. Ein VirtualPathProvider in Global.asax.cs registrieren
    public class Global : System.Web.HttpApplication
    {
       protected void Application_Start(object sender, EventArgs e)
       {
          HostingEnvironment.RegisterVirtualPathProvider(new RazorVirtualPathProvider());
       }
    ...
    
  3. In Web.Config muss der BuildProvider registriert werden:
    <configuration>
    <configSections>
    <section name="razorEngine" type="RazorEngine.Configuration.RazorEngineConfigurationSection, RazorEngine" requirePermission="false" />
    </configSections>   <razorEngine factory="RazorEngine.Web.WebCompilerServiceFactory, RazorEngine.Web" /><system.web>
    <compilation debug="true" targetFramework="4.0">
    <buildProviders>
    <add extension=".csrzr" type="RazorEngine.Web.CSharp.CSharpRazorBuildProvider, RazorEngine.Web" />
    </buildProviders>
    </compilation>

So aufgerĂŒstet kann man mit den Models und Templates beginnen. Man kann die Templates als html-Dateien speichern. Allerdings wenn man IntelliSense haben möchte, dann muss MVC3 auf den Rechner installiert und die Datei als cshtml gespeichert werden.

 

Das Beispiel hier ist ĂŒber ein MasterHeader mit dem Anfang der Seite, ein MasterFooter mit dem Ende, beide eingebettet mit " @Include(\"master...\")" in Content. Die ganze Seite bekommt ein Objekt vom Typ Model zum Parsen. Alle Templates werden mit einem ITemplateFinder geladen.

...
ITemplateFinder templateFinder = new TemplateFinder(path);
Razor.Compile(templateFinder.GetTemplate("masterHeader.cshtml"), typeof(Model), "masterHeader");
Razor.Compile(templateFinder.GetTemplate("masterFooter.cshtml"), typeof(Model), "masterFooter");

var model = new Model
{
    PurchaseNo = "011313074142",
    Amount = "270.63",
    Date = "20110121"
};

var template = templateFinder.GetTemplate("Content.cshtml");
Razor.Compile(template, typeof(Model), "content");
var parsedTemplate = Razor.Run(model, "content");
context.Response.ContentType = "text/HTML";
context.Response.Write(parsedTemplate);

Bevor ihr was ĂŒber Namen oder Verantwortlichkeiten was sagt: das Projekt wurde als Spike erstellt, und als solche hat seine Rolle  perfekt erfĂŒllt 🙂 In Produktion wĂŒrde ich das Kompilieren von statischen Templates in Application_Start verschieben und das ITemplateFinder sollte auf  jeden Fall Injected werden.

 

Ich muss mich bei den 2 Jungs, die das Projekt entwickeln, sehr bedanken, es war eine super Idee! Schaut es einfach an, die dll kann noch viel mehr.

dotnet-cologne: veni-vidi-vici!

Am letzten Freitag fand die dotnet Cologne zum 3. Mal statt. Ich habe die ersten 2 Male nicht teilgenommen, aber wie ein Freund meinte, diesmal hatte ich “Heimvorteil” 🙂 Nach der langen Pause, bedingt durch BeinbrĂŒche, UmzĂŒge und Ă€hnliche Erfahrungen, hatte ich regelrechte Entzugserscheinungen: Entzug von der Community.

Principles, patterns, and practices are important, but it’s the people who make them work. – Robert C. Martin aka Uncle Bob

Es war super! Über 300 Leute, darunter sehr-sehr viele bekannte Gesichter, riesen Freude sie wieder zu sehen. Der erste Vortrag, den ich besucht habe, hieß “Agile Architekturen” und wurde von Ilker abgehalten. Er hat zwei konkrete Beispiele – die Hexagonale Architektur von Alistair Cockburn und Data Context Interaction, der “neue MVC” – vorgestellt, samt Fallbeschreibung und Code fĂŒr jeweils ein User Case. Wir dĂŒrften/sollten uns dann eine Meinung ĂŒber die Lösungen bilden und diese Meinung auch kundtun. Es wurde schnell klar, dass jede Variante ihre Vor- und Nachteile hat, und dass die allgemein gĂŒltige “agile Architektur” nicht wirklich existiert.

 

Nach der Pause ging es dann fĂŒr mich mit Daniel “REST Wars: WCF WebHTTP vs. ASP.NET MVC” weiter. Es war eine sehr interessante und kompetente PrĂ€sentation. Am Ende hatte ich eine ganz genaue Vorstellung darĂŒber, WOZU man REST verwenden soll und welche technologische Möglichkeiten man hat. Notiz an mich: WCF WebAPI bei Codeplex anschauen.

 

Als Lunch-Session wollte ich unbedingt von Sergey ĂŒber psake hören, aber die Zeit ist bei den GesprĂ€chen mit den Jungs von User Group Karlsruhe irgendwie verflogen. DafĂŒr habe ich stattdessen Kay Giza kennengelernt 🙂 Endlich kann ich ein Gesicht zu jener Person zuordnen, die mir seit Jahren regelmĂ€ĂŸig Tipps und Empfehlungen schickt. Er hatte selbst eine Session ĂŒber MSDN vorbereitet und ich hĂ€tte ihn sehr gern gehört, aber er war parallel mit der Azure-Session und an dieser musste ich auf jedem Fall teilnehmen. Also hat Kay meine Fragen zum MSDN zwischen a flying coke ( 😉 you know what I mean) und einen Kaffee im Foyer beantwortet. Danke schön 🙂

 

Der “Überflieger” des Tages war eindeutig Bart de Smet – der Mann, der in seiner Freizeit u.a. Sudoku mit c# (Stichwort Microsoft Solver Foundation) löst.
Ich konnte leider nur den ersten von 2 VortrĂ€gen besuchen, ĂŒber “LINQ to Everything” – und das hat er wirklich wortwörtlich gemeint. (Stichwort IQbservable, IScheduler)

 

Der vorletzte Vortrag war der bereits erwĂ€hnte “Azure: Portierung einer Anwendung”. Wir haben einen kleinen Überblick von der Zusammensetzung von “the Cloud” bekommen, und die “Do’s and Dont’s” dazu. Und mir wurden diese zwei Tatsachen klar: in der Cloud alles kostet Geld und ohne Clean-Code (insbesondere ohne Dependency Injection) braucht man darĂŒber gar nicht nachzudenken. Wenn aber die Vorbedingungen erfĂŒllt sind, dann geht das Portieren super schnell und einfach.

 

Last but not least habe ich mir eine Session ĂŒber “Rich-Internet Apps & Mobile Anwendungen mit HTML5…” gegönnt, ein Thema, mit dem ich mich zur Zeit nicht direkt beschĂ€ftigen muss – zur Entspannung so zusagen 😉 Also dies war eine super Entscheidung, Tim Fischer ist ein großartiger Vortragender! Als Nebeneffekt habe ich erfahren, wie man JavaScript-Code ohne es zu schreiben generiert (Stichtwort Sencha) und was hinter dem Begriff HTML5 steckt.

 

Damit war fĂŒr mich das Pflichtprogramm zu Ende, aber natĂŒrlich nicht der Tag.
Jeder, der bei solchen Community-Events schon teilgenommen hat, weiß, dass die besten GesprĂ€che rund um Entwickler-Sein bei dem/den abschließenden Bier/en danach gefĂŒhrt werden. So hatte ich die Ehre, endlich codemurai kennen zu lernen und die Meinungen der anderen ĂŒber Themen wie “warum ist Softwareentwicklung einer MĂ€nnerdomaine” oder “Absatzmarkt China” oder “das Geheimniss hinter dem Erfolg von osteuropĂ€ischen Softwareunternehmen” zu hören.

 

Es war schön, es war anstrengend und es war sehr lehrreich.
Genauso, wie eine Konferenz sein soll.

 

Tausend Dank an das Orga-Team und an die Sprecher fĂŒr ihre großartige Arbeit und fĂŒr ihre MĂŒhe, diese Community zu stĂ€rken und zu pflegen.
“Individuals and Interactions over Processes and Tools” – wie das Agile Manifest es so schön definiert – weil wo wĂ€ren wir, wenn das nicht war wĂ€re?!

 

Das nĂ€chste Event – NOS SĂŒd 2011 – wartet schon…

Tausende Codezeilen verstehen – aber wie?

Nach 7 Wochen Zwangsurlaub (siehe unten) bin ich wieder back to life: mit einem halbwegs neuen Bein (mit Titaneinlagen und Schlitzschrauben 😉 ), in einer neuen Stadt mit 100%-er Snowcoverage, in einem neuen Job – nach einem Monat VerspĂ€tung.

Das letzte Mal, als ich bei einer Firma den Code verstehen musste, ging es um ASP-Classic. Die AbhĂ€ngigkeiten waren ĂŒberschaubar, das Debugen ging mit Response.Write-Zeilen ;). Aber wie macht man das heute, wie versteht man den bestehende Code, der in vielen Jahren aus den fleißigen Fingern der Programmierern herausgeflossen ist? Und das im Web, in einer unglaublich flexiblen E-Commerce-Anwendung…

Die Lösung war einfach: mit Unit-Tests ! Ich musste nicht erklĂ€rt bekommen haben, WAS der Code tut, nur welche Aufrufe zu welchen Ergebnissen fĂŒhren. Immer, wenn ich ein Szenario verstanden habe, wurden dafĂŒr Tests geschrieben und das Ergebnis besprochen. Der Begriff unit wurde teilweise natĂŒrlich ausgedehnt, aber das hat nichts an der Tatsachen geĂ€ndert, dass am Ende

  1. ich den Code verstanden habe
  2. die meisten analysierten Zeilen durch einen Test abgedeckt wurden
  3. die Diskussionen ĂŒber den Testnamen dazugefĂŒhrt haben, dass manch unnötige Zeilen (lese “Szenarien”) entfernt wurden, also der Code besser geworden ist

While(Ankle.IsBroken) Thread.SpinWait(1);

my broken ankle

Wie ihr seht, habe ich ein neues Dojo ausprobiert:

...
while (Ankle.IsBroken)
{
    Thread.SpinWait(1);
    Console.WriteLine("I am temporary out of order");
    KlinikumRechtsDerIsar.Heal(Ankle);
}
...

Es ist nicht mal annÀhernd so lustig wie die sonstigen Dojos, bei denen ich mitgemacht habe und ich habe den starken Verdacht, dass ich auf diese Erfahrung hÀtte locker verzichten können, aber wie der Revolvermann Roland Deschain von Gilead sagte:

Ka ist ein Rad, dachte er. Oder, was Eddie zu sagen pflegte: Was rumging, das kam auch wieder rum.

Ich komme auch wieder aber erst in 2-3 Wochen.