<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Guida</title>
    <description>The latest articles on DEV Community by David Guida (@mizrael).</description>
    <link>https://dev.to/mizrael</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F182600%2F365c06e9-54b5-4af0-97df-8d61dc875940.jpg</url>
      <title>DEV Community: David Guida</title>
      <link>https://dev.to/mizrael</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mizrael"/>
    <language>en</language>
    <item>
      <title>OpenSleigh: tackling state persistence</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Tue, 02 Mar 2021 14:01:56 +0000</pubDate>
      <link>https://dev.to/mizrael/opensleigh-tackling-state-persistence-4mbl</link>
      <guid>https://dev.to/mizrael/opensleigh-tackling-state-persistence-4mbl</guid>
      <description>&lt;p&gt;Hi All! Here we go with another article about &lt;strong&gt;&lt;a href="https://github.com/mizrael/OpenSleigh" rel="noreferrer noopener"&gt;OpenSleigh&lt;/a&gt;&lt;/strong&gt;. Today we’re going a bit deeper into the rabbit hole and see how it is dealing with state persistency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.davideguida.com/opensleigh-a-saga-management-library-for-net-core/" rel="noreferrer noopener"&gt;The last time&lt;/a&gt; we introduced the library, discussed a bit about what the Saga pattern is and what’s the general idea behind Orchestration and Choreography.&lt;/p&gt;

&lt;p&gt;Now. Sagas are all about messages. Commands get issued and events get published. At the same time though, we have to make sure that changes to the internal state of the Saga are being persisted safely. Also, we want outgoing messages to be dispatched only when the local state is saved. &lt;/p&gt;

&lt;h4&gt;
  
  
  In an ideal world, we wouldn’t have to worry about this, but unfortunately, we have to deal with a bunch of nasty stuff like concurrency and horizontal scalability.
&lt;/h4&gt;

&lt;p&gt;For example, let’s suppose that our application is composed of 2 services: a Web API and a background worker service. Let’s call them “&lt;em&gt;Orders API&lt;/em&gt;” and “&lt;em&gt;Orders processor&lt;/em&gt;“, that should help you get the picture.&lt;/p&gt;

&lt;p&gt;The Web API is responsible for receiving client requests, packing them into nice messages, and pushing them to a service bus. The worker subscribes to those messages and uses &lt;strong&gt;OpenSleigh&lt;/strong&gt; to handle Saga execution.&lt;/p&gt;

&lt;p&gt;This is a pretty nice and standard way of handling long-running operations asynchronously. Works pretty well and, most importantly, &lt;strong&gt;scales pretty well.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But what happens if we have more instances of the worker help handling the load? Suppose for a moment that the &lt;em&gt;Orders API&lt;/em&gt; pushes a _ProcessOrder ****_command for the same order “123” twice. It had a hiccup, a network glitch. Sh*t happens.&lt;/p&gt;

&lt;p&gt;Now, this &lt;em&gt;quite unfortunate&lt;/em&gt; event means that the same order will probably be processed twice. Moreover, if we have more worker instances, it might happen that both the messages will be dispatched and processed &lt;em&gt;concurrently&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;How does &lt;strong&gt;OpenSleigh&lt;/strong&gt; handle these situations?&lt;/p&gt;

&lt;p&gt;First of all, we can assume that the &lt;em&gt;ProcessOrder&lt;/em&gt; command starts the &lt;em&gt;ProcessOrderSaga&lt;/em&gt;. Each &lt;strong&gt;OpenSleigh&lt;/strong&gt; Saga has a configurable unique ID, which is used also as &lt;em&gt;&lt;a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/CorrelationIdentifier.html" rel="noreferrer noopener"&gt;correlation ID&lt;/a&gt;&lt;/em&gt;. In this case, I think it’s safe to use the Order ID to populate this value.&lt;/p&gt;

&lt;p&gt;When the &lt;em&gt;Orders processor&lt;/em&gt; service receives a message, &lt;strong&gt;OpenSleigh&lt;/strong&gt; will extract the correlation id and use it to fetch the right Saga state from the persistence storage. &lt;/p&gt;

&lt;p&gt;If no existing Saga State is available, we check if that message is capable of starting a new Saga. If so, we’ll get a shiny new instance and we can finally get down to business.&lt;/p&gt;

&lt;p&gt;That’s all for today. &lt;a href="https://www.davideguida.com/opensleigh-tackling-state-persistence-part-2/"&gt;The next time&lt;/a&gt; we’ll continue analyzing the flow and we’ll see some code. Ciao!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>microservices</category>
      <category>pubsub</category>
      <category>messagequeues</category>
    </item>
    <item>
      <title>Dynamic method invocation with .NET Core</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Fri, 05 Feb 2021 20:22:05 +0000</pubDate>
      <link>https://dev.to/mizrael/dynamic-method-invocation-with-net-core-4cmo</link>
      <guid>https://dev.to/mizrael/dynamic-method-invocation-with-net-core-4cmo</guid>
      <description>&lt;p&gt;Hi All! Today we're going to explore few ways to perform "&lt;em&gt;dynamic method invocation&lt;/em&gt;" with .NET Core.&lt;/p&gt;

&lt;p&gt;As some of you know already, a while ago I started working on an open-source project, &lt;a href="https://www.davideguida.com/opensleigh-a-saga-management-library-for-net-core/?swcfpc=1"&gt;OpenSleigh&lt;/a&gt;. It's a Saga management library for .NET Core applications.&lt;/p&gt;

&lt;p&gt;I have been focusing on it a lot in the last period, and this, unfortunately, led me to be less diligent with my blog. I have several articles in my backlog, looking for the right time to jump off the hat.&lt;/p&gt;

&lt;p&gt;Anyways, while working on the first prototypes of OpenSleigh (BTW, make sure to at least fork or star &lt;a href="https://github.com/mizrael/OpenSleigh"&gt;the repository&lt;/a&gt;!), I had to face a bunch of times an interesting problem.&lt;/p&gt;

&lt;p&gt;Let me try to summarize it very quickly:&lt;/p&gt;

&lt;h4&gt;
  
  
  What if we have to call a method on some instance, but the only thing we know is the method signature and not the class type?
&lt;/h4&gt;

&lt;p&gt;It's a tricky situation, but luckily for us, .NET has a few ways to get to the destination.&lt;/p&gt;

&lt;p&gt;The problem now is: which one is the best?&lt;/p&gt;

&lt;p&gt;So I decided to give it a try and write some benchmarks. I've tested:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; direct method invocation&lt;/li&gt;
&lt;li&gt; &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo.invoke?view=netframework-1.1&amp;amp;WT.mc_id=DOP-MVP-5003878"&gt;MethodInfo.Invoke&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.delegate.dynamicinvoke?view=net-5.0&amp;amp;WT.mc_id=DOP-MVP-5003878"&gt;Delegate.DynamicInvoke&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.func-1?view=net-5.0&amp;amp;WT.mc_id=DOP-MVP-5003878"&gt;Func&amp;lt;&amp;gt;&lt;/a&gt; invocation&lt;/li&gt;
&lt;li&gt; &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic?WT.mc_id=DOP-MVP-5003878"&gt;dynamic &lt;/a&gt;cast&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course, *direct method invocation *is used as a comparison, a baseline for all the other techniques.&lt;/p&gt;

&lt;p&gt;Let's suppose we have this small class here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Foo
{
    public int Bar(int a, int b, bool c) =&amp;gt; a + (c ? b : 0);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we want to call &lt;em&gt;Bar() *on an instance, but all we have is an *object.&lt;/em&gt; Let's take a look at each technique.&lt;/p&gt;

&lt;h5&gt;
  
  
  MethodInfo.Invoke
&lt;/h5&gt;

&lt;p&gt;We simply start by storing a &lt;em&gt;MethodInfo&lt;/em&gt; reference to &lt;em&gt;Bar()&lt;/em&gt; and then we simply invoke it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;object fooInstance = ...; // we get this from somewhere else
MethodInfo barMethod = ClassType.GetMethod(nameof(Foo.Bar));
barMethod.Invoke(fooInstance, new[] { (object)1, (object)2, (object)false });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Delegate.DynamicInvoke
&lt;/h5&gt;

&lt;p&gt;In this case, instead, we start off by getting a &lt;em&gt;MethodInfo *reference, but we wrap it into a typed *Delegate&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;object fooInstance = ...; // we get this from somewhere else
MethodInfo barMethod = ClassType.GetMethod(nameof(Foo.Bar));
var delegateType = Expression.GetDelegateType(typeof(Foo), typeof(int), typeof(int), typeof(bool), typeof(int));
var @delegate = Delegate.CreateDelegate(delegateType, barMethod);
@delegate.DynamicInvoke(new[] { fooInstance, (object)1, (object)2, (object)false });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Func&amp;lt;&amp;gt; invocation
&lt;/h5&gt;

&lt;p&gt;Similar to the previous one, but we also cast the &lt;em&gt;Delegate *to a *Func&amp;lt;&amp;gt;&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;object fooInstance = ...; // we get this from somewhere else
MethodInfo barMethod = ClassType.GetMethod(nameof(Foo.Bar));
var delegateType = Expression.GetDelegateType(typeof(Foo), typeof(int), typeof(int), typeof(bool), typeof(int));
var func = (Func&amp;lt;Foo, int, int, bool, int&amp;gt;)Delegate.CreateDelegate(delegateType, barMethod);
func(fooInstance as Foo, 1, 2, false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one seems a little bit "shady", since we actually know that the instance is of type &lt;em&gt;Foo.&lt;/em&gt; But still, I decided to add it to the group since it might still come useful.&lt;/p&gt;

&lt;h5&gt;
  
  
  Dynamic cast
&lt;/h5&gt;

&lt;p&gt;This one is the easiest to code (after the direct invocation of course), as it's basically just a cast to &lt;em&gt;dynamic&lt;/em&gt; and a method call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;object fooInstance = ...; // we get this from somewhere else
dynamic dynamicFoo = fooInstance as dynamic;
dynamicFoo.Bar(1, 2, false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, after all this fuss, who's the winner? I guess an image is worth thousand words:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b8D_gi_Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/github.com/mizrael/BenchmarkDynamicInvocation/raw/main/benchmark.jpg%3Fw%3D788%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b8D_gi_Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/github.com/mizrael/BenchmarkDynamicInvocation/raw/main/benchmark.jpg%3Fw%3D788%26ssl%3D1" alt="Results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So as you can see, calling a method directly, is definitely the fastest way. Followed immediately by the "shady" *Func&amp;lt;&amp;gt; *call and then the *dynamic *cast.&lt;/p&gt;

&lt;p&gt;As usual, I've pushed the &lt;a href="https://github.com/mizrael/BenchmarkDynamicInvocation"&gt;code to GitHub&lt;/a&gt;, so feel free to run your experiments and let me know!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to do Document-level locking on MongoDB and .NET Core</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Mon, 11 Jan 2021 22:04:00 +0000</pubDate>
      <link>https://dev.to/mizrael/how-to-do-document-level-locking-on-mongodb-and-net-core-4jhi</link>
      <guid>https://dev.to/mizrael/how-to-do-document-level-locking-on-mongodb-and-net-core-4jhi</guid>
      <description>&lt;p&gt;Hi All! Today we're going to see how MongoDB handles locks and how we can achieve Document-level locking.&lt;/p&gt;

&lt;p&gt;The default MongoDB storage engine, &lt;em&gt;&lt;a href="https://docs.mongodb.com/manual/core/wiredtiger/"&gt;WiredTiger&lt;/a&gt;,&lt;/em&gt; uses optimistic concurrency control, or OCC. In a nutshell, it assumes that&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;multiple transactions can frequently complete without interfering with each other.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Optimistic_concurrency_control#:~:text=Optimistic%20concurrency%20control%20(OCC)%20is,without%20interfering%20with%20each%20other."&gt;WIKIPEDIA&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This basically means we're somewhat sure that nobody else is going to update our data while we're working on it.&lt;/p&gt;

&lt;h4&gt;
  
  
  In case that happens, one operation is going to succeed, while the others will fail, entering some kind of retry loop.
&lt;/h4&gt;

&lt;p&gt;We're relying on the nature of the data and the operations available on the Domain. In short, we're being &lt;em&gt;optimistic&lt;/em&gt; that things will end up just fine.&lt;/p&gt;

&lt;p&gt;When we want to be absolutely sure that only one consumer will be able to operate a specific set of data, we could use some form of locking.&lt;/p&gt;

&lt;p&gt;This falls into the realm of &lt;em&gt;Pessimistic Locking&lt;/em&gt;: we block access to the data till we're done with it. The drawback is simple: what if we never release a lock? The other consumers will deadlock, so we need a proper strategy (for example timeouts) to handle those cases.&lt;/p&gt;

&lt;p&gt;It can get complicated and ugly pretty quickly so be careful.&lt;/p&gt;

&lt;p&gt;There might be some situations, however, where you need more fine control over the locking strategy, for example when you're dealing with &lt;a href="https://www.davideguida.com/opensleigh-a-saga-management-library-for-net-core/?swcfpc=1"&gt;Sagas and Distributed Transactions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, WiredTiger &lt;a href="https://docs.mongodb.com/manual/faq/concurrency/"&gt;allows locking&lt;/a&gt; only at the global, database or collection levels. This means that we cannot lock a single document.&lt;/p&gt;

&lt;p&gt;Luckily for us, operations on MongoDB are atomic, so we can "fake" some sort of pessimistic locking and handle part of the complexity on the application side.&lt;/p&gt;

&lt;p&gt;The idea is to decorate every document with two additional properties, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "LockId" : UUID("6ca9d76f-01ac-42cc-88ca-b2ecd5b286c3"),
    "LockTime" : ISODate("2020-12-28T04:42:13.528Z")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we want to lock a document, we fetch it by ID but we also make sure that &lt;em&gt;LockId&lt;/em&gt; is null. Additionally, we can also check that &lt;em&gt;LockTime&lt;/em&gt; is after a specific window: this way we can discard previous locks if they're expired.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using the &lt;a href="https://api.mongodb.com/csharp/current/html/M_MongoDB_Driver_IMongoCollection_1_FindOneAndUpdateAsync__1.htm"&gt;&lt;em&gt;FindOneAndUpdateAsync&lt;/em&gt; &lt;/a&gt;API, we can fetch the document and in the same operation, we can set both &lt;em&gt;LockId&lt;/em&gt; and &lt;em&gt;LockTime&lt;/em&gt;.
&lt;/h4&gt;

&lt;p&gt;We'll also configure the call to be an &lt;em&gt;upsert&lt;/em&gt;: this way if the document is not in the DB yet, we can also create it. Moreover, the next time someone is trying to access it, the engine will throw a &lt;em&gt;MongoCommandException&lt;/em&gt; instead.&lt;/p&gt;

&lt;p&gt;When we're done with the document, we can release it by simply setting to null both &lt;em&gt;LockId&lt;/em&gt; and &lt;em&gt;LockTime&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Just for you to know, a while ago I started working on &lt;a href="https://github.com/mizrael/OpenSleigh"&gt;OpenSleigh&lt;/a&gt;, a distributed saga management library for .NET Core. It uses the same technique in its MongoDB &lt;a href="https://github.com/mizrael/OpenSleigh/blob/develop/src/OpenSleigh.Persistence.Mongo/MongoSagaStateRepository.cs"&gt;persistence driver&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.davideguida.com/how-to-do-document-level-locking-on-mongodb-and-net-core-part-2/?swcfpc=1"&gt;next time&lt;/a&gt; we'll see a small demo and dig a bit more into the details. Stay tuned!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>OpenSleigh: a Saga management library for .NET Core</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Mon, 11 Jan 2021 19:55:32 +0000</pubDate>
      <link>https://dev.to/mizrael/opensleigh-a-saga-management-library-for-net-core-18j1</link>
      <guid>https://dev.to/mizrael/opensleigh-a-saga-management-library-for-net-core-18j1</guid>
      <description>&lt;p&gt;Hi All! Today I want to talk a bit about a pet project of mine I've been working on in the last few weeks. I called it &lt;em&gt;&lt;a href="https://github.com/mizrael/OpenSleigh"&gt;OpenSleigh&lt;/a&gt;&lt;/em&gt;, it's a Saga management library for .NET Core.&lt;/p&gt;

&lt;p&gt;For those who don't know what the Saga Pattern is, Chris Richardson has a very good introduction &lt;a href="https://microservices.io/patterns/data/saga.html"&gt;on his website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The basic idea is quite interesting: in a micro-service architecture, it often happens that we need to handle several long-running operations that span multiple services. &lt;a href="https://www.davideguida.com/improving-microservices-reliability-part-1-two-phase-commit/"&gt;Distributed transactions&lt;/a&gt; are a nasty little beast and we also need a way to keep track of the global status and manage the whole flow.&lt;/p&gt;

&lt;h4&gt;
  
  
  There are two main schools of thought for this: &lt;strong&gt;&lt;em&gt;Choreography&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Orchestration&lt;/em&gt;&lt;/strong&gt;.
&lt;/h4&gt;

&lt;p&gt;With &lt;strong&gt;Choreography&lt;/strong&gt; the logic is decentralized, scattered and shared amongst the participants. They usually communicate using a Message Broker, like RabbitMQ or Kafka, which makes definitely easier adding and removing message publishers and consumers.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Orchestration&lt;/strong&gt; instead, the logic is centralised in a single component, which is in charge of the entire workflow. Once the process is triggered, this &lt;em&gt;orchestrator&lt;/em&gt; will take care of calling each microservice (directly or via messaging) and handling responses and faults.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenSleigh&lt;/strong&gt; falls into the realm of the orchestrators. It can be added to regular Console or Web applications, will spin up a bunch of &lt;strong&gt;&lt;a href="https://www.davideguida.com/consuming-message-queues-using-net-core-background-workers-part-3-the-code-finally/"&gt;BackgroundServices&lt;/a&gt;,&lt;/strong&gt; and do its magic.&lt;/p&gt;

&lt;p&gt;The Core module of &lt;strong&gt;OpenSleigh&lt;/strong&gt; can be installed from &lt;a href="https://www.nuget.org/packages/OpenSleigh.Core/"&gt;NuGet&lt;/a&gt;. However, Transport and Persistence packages are necessary to properly use the library.&lt;/p&gt;

&lt;p&gt;These are the packages available at the moment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.nuget.org/packages/OpenSleigh.Persistence.InMemory/"&gt;OpenSleigh.Persistence.InMemory&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nuget.org/packages/OpenSleigh.Persistence.Mongo/"&gt;OpenSleigh.Persistence.Mongo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.nuget.org/packages/OpenSleigh.Transport.RabbitMQ/"&gt;OpenSleigh.Transport.RabbitMQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, there are already several valuable alternatives on the market, like &lt;a href="https://masstransit-project.com/"&gt;MassTransit&lt;/a&gt; and &lt;a href="https://particular.net/nservicebus"&gt;NServiceBus&lt;/a&gt;. So why did I started this project?&lt;/p&gt;

&lt;h4&gt;
  
  
  Because I was &lt;strong&gt;curious&lt;/strong&gt;. And I'm pretty damn sure many of you can relate.
&lt;/h4&gt;

&lt;p&gt;I wanted to see how a Saga system works from the inside. Also, I wondered if I could build one myself from scratch. I wanted to create an open-source project and create a community around it.&lt;/p&gt;

&lt;p&gt;So don't hesitate! Take a look at&lt;a href="https://github.com/mizrael/OpenSleigh"&gt; the repository&lt;/a&gt; on GitHub, download the packages, play with them, and send me your feedback!&lt;/p&gt;

</description>
      <category>patterns</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>microservices</category>
    </item>
    <item>
      <title>ASP.NET Core structured logging - introduction</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Tue, 08 Dec 2020 14:52:13 +0000</pubDate>
      <link>https://dev.to/mizrael/asp-net-core-structured-logging-introduction-2aj0</link>
      <guid>https://dev.to/mizrael/asp-net-core-structured-logging-introduction-2aj0</guid>
      <description>&lt;p&gt;Hi All! In this post, we'll see what's the difference between "&lt;em&gt;standard&lt;/em&gt;" and "&lt;em&gt;structured&lt;/em&gt;" logging and how the latter can help us tracing down issues in our systems.&lt;/p&gt;

&lt;p&gt;But first, let's begin with a question. Ever had to go through countless log messages to find a single tiny entry?&lt;/p&gt;

&lt;p&gt;Then you know how it feels like.&lt;/p&gt;

&lt;p&gt;*Standard *logging represents the simplest form possible. It's just a simple message, possibly correlated with a timestamp and probably a few other pieces of data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"creating customer 123..."
"an exception has been thrown by..."
"something, somewhere, went terribly, terribly wrong"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe, if you're lucky you also get a bit of stack trace.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding logging to an ASP.NET application is &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1"&gt;quite easy&lt;/a&gt;, although configuring it properly can be sometimes tricky.
&lt;/h4&gt;

&lt;p&gt;Knowing &lt;strong&gt;what&lt;/strong&gt; to log instead is the real deal. We don't want to lose important information but at the same time, we have to avoid polluting the system with unnecessary messages.&lt;/p&gt;

&lt;p&gt;Now, the problem with *standard *logging is that searching for specific entries can become difficult. Very difficult, especially when our system has been online and used for a while.&lt;/p&gt;

&lt;p&gt;Filtering and potentially doing some aggregation is doable but the quality of results is questionable. There are multiple tools that can help us with this, like &lt;a href="https://grafana.com/"&gt;Grafana&lt;/a&gt; and &lt;a href="https://www.splunk.com/"&gt;Splunk&lt;/a&gt; (and do much more than that, to be fair).&lt;/p&gt;

&lt;p&gt;So what other option do we have? Well, we can move to &lt;strong&gt;&lt;em&gt;structured&lt;/em&gt;&lt;/strong&gt; logging instead. What's the difference? Well, basically we're &lt;strong&gt;enriching&lt;/strong&gt; the log entry with some additional data, regardless of the actual text message.&lt;/p&gt;

&lt;p&gt;These fields can then be used later on to filter the entries, create aggregation, stats and charts. All this data is of course extremely useful, helping us monitoring and keeping under control the health of our systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  Now, obviously, if your application is creating just a hundred messages per day, you won't find much benefit from all of this. Just come up with a decent Regexp and you're good to go.
&lt;/h4&gt;

&lt;p&gt;This, of course, doesn't mean that you'll have to start throwing more messages just for the sake of it. All the opposite.&lt;/p&gt;

&lt;p&gt;But if you're orchestrating a large microservice application, with a lot of moving parts, possibly with complex architectures like &lt;a href="https://www.davideguida.com/event-sourcing-in-net-core-part-1-a-gentle-introduction/?swcfpc=1"&gt;Event Sourcing&lt;/a&gt;, then you want to be careful.&lt;/p&gt;

&lt;p&gt;If we're being diligent and keeping field naming consistent, structured logging will help us track down the flow of our transactions amongst the different services. Yes, it can be hard, especially when there are multiple teams working on separate microservices.&lt;/p&gt;

&lt;p&gt;In this case, things like &lt;a href="https://devblogs.microsoft.com/aspnet/improvements-in-net-core-3-0-for-troubleshooting-and-monitoring-distributed-apps/"&gt;Trace identificators&lt;/a&gt; are the key solution to our problem.&lt;/p&gt;

&lt;p&gt;That's all for today. &lt;a href="https://www.davideguida.com/asp-net-core-structured-logging-part-2-the-infrastructure/?swcfpc=1"&gt;In another article&lt;/a&gt; we'll see some examples and how to leverage structured logging in our ASP.NET Core application.&lt;/p&gt;

</description>
      <category>logging</category>
      <category>dotnet</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Blazor and 2D game development – part 1: intro</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Tue, 01 Dec 2020 13:48:41 +0000</pubDate>
      <link>https://dev.to/mizrael/blazor-and-2d-game-development-part-1-intro-2oig</link>
      <guid>https://dev.to/mizrael/blazor-and-2d-game-development-part-1-intro-2oig</guid>
      <description>&lt;p&gt;Every now and then I go back to &lt;strong&gt;game development&lt;/strong&gt;. It's literally what brought me into this world of coding, something like 32 years ago. This time I decided to do some experiments with &lt;strong&gt;Blazor&lt;/strong&gt; and &lt;strong&gt;2D graphics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I don't have a precise goal in mind right now, just playing around.&lt;/p&gt;

&lt;p&gt;Probably this late-night fever started when I wrote about &lt;a href="https://www.davideguida.com/how-to-consume-dd-rest-api-over-grpc-web-blazor-part-1-the-client/?swcfpc=1" rel="noopener noreferrer"&gt;D&amp;amp;D, Blazor and gRPC services&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  For those interested, &lt;a href="https://github.com/mizrael/BlazorCanvas" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt; you can find a repository with all the examples I'll be able to come up with.
&lt;/h4&gt;

&lt;p&gt;For now, I decided to proceed at incremental steps and write small features, one on top of the other. As of today, this is the current list:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/BlazorCanvas.Example1" rel="noopener noreferrer"&gt;Example 1&lt;/a&gt; shows how to initialize the 2d canvas&lt;/li&gt;
&lt;li&gt; in &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/BlazorCanvas.Example2" rel="noopener noreferrer"&gt;example 2&lt;/a&gt; we see how to render a sprite and react to the window resize event&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/BlazorCanvas.Example3" rel="noopener noreferrer"&gt;Example 3&lt;/a&gt; shows how to move a sprite on the screen&lt;/li&gt;
&lt;li&gt; Then in &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/BlazorCanvas.Example4" rel="noopener noreferrer"&gt;example 4&lt;/a&gt;, we build on top of the previous one, refactoring and cleaning up the code&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/BlazorCanvas.Example5" rel="noopener noreferrer"&gt;Example 5&lt;/a&gt; shows how to handle mouse inputs&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/BlazorCanvas.Example6" rel="noopener noreferrer"&gt;Example 6&lt;/a&gt; shows how to animate a sprite. I downloaded the spritesheets from &lt;a href="https://luizmelo.itch.io/medieval-warrior-pack-2" rel="noopener noreferrer"&gt;here&lt;/a&gt; and combined them using &lt;a href="https://github.com/mizrael/BlazorCanvas/tree/master/tools/AnimatedSpritesProcessor" rel="noopener noreferrer"&gt;a custom tool&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will try to write an article for every example, it will also serve as reminder of my train of thought and how I managed to get the code in that shape.&lt;/p&gt;

&lt;p&gt;As I wrote previously, I don't have a precise goal at the moment. I *might *end up with something playable, although I tend to change idea quite often on this matter. As many of us, I can get distracted quite easily by new shiny toys. Or simply by life &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs.w.org%2Fimages%2Fcore%2Femoji%2F13.0.0%2Fsvg%2F1f642.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs.w.org%2Fimages%2Fcore%2Femoji%2F13.0.0%2Fsvg%2F1f642.svg" alt="🙂"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.davideguida.com/blazor-gamedev-part-2-canvas-initialization/?swcfpc=1" rel="noopener noreferrer"&gt;next time&lt;/a&gt; we'll start by initializing the Canvas and rendering some text.&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>dotnet</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>How to migrate Blazor Webassembly to .NET 5</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Mon, 30 Nov 2020 02:34:01 +0000</pubDate>
      <link>https://dev.to/mizrael/how-to-migrate-blazor-webassembly-to-net-5-hmm</link>
      <guid>https://dev.to/mizrael/how-to-migrate-blazor-webassembly-to-net-5-hmm</guid>
      <description>&lt;p&gt;.NET 5 is out today! It's a big milestone and comes with &lt;a href="https://devblogs.microsoft.com/dotnet/announcing-net-5-0/?WT.mc_id=DOP-MVP-5003878"&gt;a huge list&lt;/a&gt; of improvements. I've been working a bit with &lt;strong&gt;Blazor &lt;/strong&gt;lately, trying to brush up &lt;a href="https://www.davideguida.com/blazor-and-2d-game-development-part-1-intro/?swcfpc=1"&gt;my gamedev skills&lt;/a&gt; again. So I took the chance and decided to upgrade &lt;a href="https://github.com/mizrael/Blazeroids"&gt;my little pet project&lt;/a&gt; to the latest version :)&lt;/p&gt;

&lt;p&gt;The first thing to do is to &lt;a href="https://visualstudio.microsoft.com/downloads/?WT.mc_id=DOP-MVP-5003878"&gt;install or update&lt;/a&gt; Visual Studio 2019 to version 16.8.0. For those interested, the release notes are &lt;a href="https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes#16.8.0"&gt;available here&lt;/a&gt;. In case you're using a different IDE (or you're on Linux/Mac), you can directly download &lt;a href="https://dotnet.microsoft.com/download/dotnet/5.0?WT.mc_id=DOP-MVP-5003878"&gt;the .NET 5 SDK&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;Once you've done installing, fire up your &lt;strong&gt;Blazor&lt;/strong&gt; project and open the .csproj file. We're going to change few little things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; At the very top, update the SDK from &lt;em&gt;Microsoft.NET.Sdk.Web&lt;/em&gt; to &lt;em&gt;Microsoft.NET.Sdk.BlazorWebAssembly&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2. Set the &lt;em&gt;TargetFramework&lt;/em&gt; to &lt;em&gt;net5.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3. In case you have it, remove the package reference to &lt;em&gt;&lt;a href="https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Build"&gt;Microsoft.AspNetCore.Components.WebAssembly.Build&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;4. Update your Nuget dependencies&lt;/p&gt;

&lt;p&gt;Now make sure you Clean your entire solution, otherwise, the build engine won't be able to re-generate all the required files with the updated framework.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>dotnet</category>
      <category>net5</category>
    </item>
    <item>
      <title>Write a WordPress blog with…Blazor!</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Mon, 30 Nov 2020 02:31:25 +0000</pubDate>
      <link>https://dev.to/mizrael/write-a-wordpress-blog-with-blazor-15d4</link>
      <guid>https://dev.to/mizrael/write-a-wordpress-blog-with-blazor-15d4</guid>
      <description>&lt;p&gt;Yeah, I'm not getting crazy. It is 100% possible to replace your &lt;strong&gt;WordPress &lt;/strong&gt;theme with a &lt;strong&gt;Blazor Webassembly&lt;/strong&gt; application.&lt;/p&gt;

&lt;p&gt;How? Well, it's not that hard actually. It's been a while now since WordPress has started exposing a quite nice &lt;a href="https://developer.wordpress.org/rest-api/"&gt;REST API&lt;/a&gt;. The first draft was added with &lt;a href="https://wordpress.org/support/wordpress-version/version-4-4/#for-developers"&gt;version 4.4&lt;/a&gt;, but it's with &lt;a href="https://wordpress.org/support/wordpress-version/version-4-7/#rest-api-content-endpoints"&gt;version 4.7&lt;/a&gt; that it gained full momentum.&lt;/p&gt;

&lt;p&gt;The API itself is definitely easy to use. The base endpoint looks something like "&lt;em&gt;&lt;a href="http://yoursite.com/wp-json/wp/v2"&gt;yoursite.com/wp-json/wp/v2&lt;/a&gt;&lt;/em&gt;".&lt;/p&gt;

&lt;h4&gt;
  
  
  From that you can start managing &lt;em&gt;&lt;a href="https://wordpress.org/news/wp-json/wp/v2/posts/"&gt;posts&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href="https://wordpress.org/news/wp-json/wp/v2/users/"&gt;users&lt;/a&gt;, &lt;a href="https://wordpress.org/news/wp-json/wp/v2/users/"&gt;comments&lt;/a&gt;&lt;/em&gt;...well you got the idea.
&lt;/h4&gt;

&lt;p&gt;This opens the door to a wide range of scenarios, for example, we could use WordPress as a &lt;a href="https://en.wikipedia.org/wiki/Headless_content_management_system"&gt;headless CMS&lt;/a&gt; and write multiple frontends based on our needs. Mobile apps, SPAs, PWAs and so on.&lt;/p&gt;

&lt;p&gt;Just to showcase how easy it is, let's see how we can quickly write a frontend blogging app using &lt;strong&gt;Blazor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, &lt;a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing"&gt;CORS &lt;/a&gt;should be enabled by default. If it isn't, a quick search on google should give you &lt;a href="https://www.google.com/search?q=wordpress+rest+api+enable+cors"&gt;the answer&lt;/a&gt;. For the sake of the exercise, let's suppose it is, so we can safely use &lt;strong&gt;Blazor &lt;/strong&gt;in &lt;strong&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-5.0&amp;amp;WT.mc_id=DOP-MVP-5003878#blazor-webassembly"&gt;Webassembly &lt;/a&gt;&lt;/strong&gt;mode.&lt;/p&gt;

&lt;p&gt;Once we've created our project, the next step is to add a reference to the &lt;a href="https://github.com/wp-net/WordPressPCL"&gt;WordPressPCL &lt;/a&gt;Nuget library. It's a handy project, that will spare us the time to write the API client ourselves.&lt;/p&gt;

&lt;p&gt;Once it's installed, we can register the client on the Composition Root in the &lt;a href="https://github.com/mizrael/BlazorWPBlog/blob/develop/src/BlazorWPBlog.UI/Program.cs"&gt;Program.cs&lt;/a&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var wpApiEndpoint = builder.Configuration["WP_Endpoint"];
var client = new WordPressClient(wpApiEndpoint);
builder.Services.AddSingleton(client);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we're basically done! Every time we want to, for example, read posts or anything, all we have to do is inject the &lt;a href="https://github.com/wp-net/WordPressPCL/blob/master/WordPressPCL/WordPressClient.cs"&gt;WordPressClient &lt;/a&gt;instance and use it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var postsQuery = new PostsQueryBuilder()
    {
        Page = 1,
        PerPage = 10,
        Order = Order.DESC,
        OrderBy = PostsOrderBy.Date
    };
var posts = await WPClient.Posts.Query(postsQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have created a &lt;a href="https://github.com/mizrael/BlazorWPBlog"&gt;small repo&lt;/a&gt; on GitHub as usual with some handy examples. I also added a &lt;a href="https://github.com/mizrael/BlazorWPBlog/blob/develop/.github/workflows/gh-pages.yml"&gt;GitHub Action&lt;/a&gt; pipeline that will deploy the code to &lt;a href="https://mizrael.github.io/BlazorWPBlog/"&gt;GitHub Pages&lt;/a&gt;, so you can see how it would look like.&lt;/p&gt;

&lt;p&gt;For detailed instructions on how to host a Blazor Webassembly application on GitHub Pages, you can take a look at &lt;a href="https://www.davideguida.com/how-to-deploy-blazor-webassembly-on-github-pages-using-github-actions/?swcfpc=1"&gt;my previous post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See ya!&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>blazor</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to deploy Azure Function Apps with Powershell</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Tue, 24 Nov 2020 15:23:42 +0000</pubDate>
      <link>https://dev.to/mizrael/how-to-deploy-azure-function-apps-with-powershell-4i7g</link>
      <guid>https://dev.to/mizrael/how-to-deploy-azure-function-apps-with-powershell-4i7g</guid>
      <description>&lt;p&gt;Hi All! Today I want to show a quick'n'dirty way to easily deploy your projects to Azure using Powershell.&lt;/p&gt;

&lt;p&gt;I've been working a lot recently with Azure Functions and Web Apps. And of course, each time I'm confident with my code, I want to see it deployed on the Cloud.&lt;/p&gt;

&lt;p&gt;Of course in an ideal world, we all would have a nice CI/CD pipeline, potentially on &lt;a href="https://azure.microsoft.com/en-us/services/devops/?WT.mc_id=DOP-MVP-5003878"&gt;Azure DevOps&lt;/a&gt;. It might happen, however, that for one reason or another, you can only get up to CI, without being able to deploy.&lt;/p&gt;

&lt;p&gt;So the only option you have is to manually handle deployments, most likely from your local machine. But what happens if you have to deploy it to multiple destinations?&lt;/p&gt;

&lt;p&gt;In my case, for example, I had to deploy a Function App and a Web App to multiple client subscriptions. Of course, you can always do this &lt;a href="https://docs.microsoft.com/en-us/visualstudio/deployment/quickstart-deploy-to-azure?view=vs-2019&amp;amp;WT.mc_id=DOP-MVP-5003878"&gt;directly from Visual Studio&lt;/a&gt;, but it still feels like a lot of manual work.&lt;/p&gt;

&lt;h4&gt;
  
  
  What if instead you can have a very nice script that handles all the grunt work for you?
&lt;/h4&gt;

&lt;p&gt;Moreover, you could potentially reuse it when you finally manage to get to the Continuous Deployment part.&lt;/p&gt;

&lt;p&gt;So, the first step is to create the &lt;a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/artifacts/artifacts-overview?view=azure-devops&amp;amp;WT.mc_id=DOP-MVP-5003878"&gt;Release Artifact&lt;/a&gt;. I am assuming, of course, that you've run already &lt;a href="https://www.davideguida.com/testing-azure-functions-on-azure-devops-part-1-setup/?swcfpc=1"&gt;your Tests&lt;/a&gt; and everything went fine.&lt;/p&gt;

&lt;p&gt;My weapon of choice for these scripts today, will be Powershell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function publish{
    param(
        $projectName        
    )

    $projectPath="src/$($projectName)/$($projectName).csproj"
    $publishDestPath="publish/" + [guid]::NewGuid().ToString()

    log "publishing project '$($projectName)' in folder '$($publishDestPath)' ..." 
    dotnet publish $projectPath -c Release -o $publishDestPath

    $zipArchiveFullPath="$($publishDestPath).Zip"
    log "creating zip archive '$($zipArchiveFullPath)'"
    $compress = @{
        Path = $publishDestPath + "/*"
        CompressionLevel = "Fastest"
        DestinationPath = $zipArchiveFullPath
    }
    Compress-Archive @compress

    log "cleaning up ..."
    Remove-Item -path "$($publishDestPath)" -recurse

    return $zipArchiveFullPath
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I'm building a temporary path using a GUID and calling *&lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?WT.mc_id=DOP-MVP-5003878"&gt;dotnet publish&lt;/a&gt; *to compile the Project and output the binaries to it. Then we generate a Zip archive and get rid of the publish folder.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;log *function is just a simple wrapper over *Write-Host&lt;/em&gt;, I just added some fancy colors to highlight the text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function log{
    param(
        $text
    )

    write-host $text -ForegroundColor Yellow -BackgroundColor DarkGreen
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have our Artifact, the next step is to deploy it to Azure. If you, like me, are working with Azure Functions, this is the script for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function deploy{
    param(
        $zipArchiveFullPath,
        $subscription,
        $resourceGroup,
        $appName
    )

    log "deploying '$($appName)' to Resource Group '$($resourceGroup)' in Subscription '$($subscription)' from zip '$($zipArchiveFullPath)' ..."
    az functionapp deployment source config-zip -g "$($resourceGroup)" -n "$($appName)" --src "$($zipArchiveFullPath)" --subscription "$($subscription)"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It simply takes the full path to the zip archive we produced before and the name of the destination Azure Subscription, Resource Group and Application. Easy peasy.&lt;/p&gt;

&lt;p&gt;Now, I've found particularly handy to set some basic application settings, right after the deployment. For this, I keep a simple JSON file with key/value pairs and deploy it using this script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function setConfig{
    param(
        $subscription,
        $resourceGroup,
        $appName,
        $configPath
    )
    log "updating application config..."
    az functionapp config appsettings set --name "$($appName)" --resource-group "$($resourceGroup)" --subscription "$($subscription)" --settings @$configPath
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The config file can be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "FUNCTIONS_WORKER_RUNTIME": "dotnet",
  "ASPNETCORE_ENVIRONMENT": "DEV",
  "Foo": "bar"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step is to put everything together and call it. I would suggest creating a separate script with all the previous functions. We can use it as a "library" and if we're lucky enough, it won't even change much when we move to CD.&lt;/p&gt;

&lt;p&gt;For our &lt;em&gt;local&lt;/em&gt; deployment script we will instead need two more helper functions. The first one will take care of the Artifact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createArtifact {
    param(
        $appName
    )
    $zipPath = publish $appName
    if ($zipPath -is [array]) {
        $zipPath = $zipPath[$zipPath.Length - 1]
    }
    return $zipPath
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can't, unfortunately, call directly the &lt;em&gt;publish *function because seems that the output from the *dotnet publish&lt;/em&gt; command will mess a bit with the return value. So we'll need to do some magic tricks, but not that much.&lt;/p&gt;

&lt;p&gt;Then we can send the artifact to the cloud:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function deployInstance {
    param(
        $zipPath,
        $subscription,
        $resourceGroup,
        $appName,
        $configPath
    )

    deploy $zipPath $subscription $resourceGroup $appName

    if(![string]::IsNullOrEmpty($configPath)){
        setConfig $subscription $resourceGroup $appName $configPath
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you remember, at the top of the post I said that we might have to deploy the same artifact to multiple destinations. Now that we have everything in place, all we have to do is just put the pieces together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$zipPath = createArtifact "MyAwesomeProject"
deployInstance $zipPath "MyFirstSubscription" "MyFirstResourceGroup" "MyAwesomeProject1" "DEV.settings.json"
deployInstance $zipPath "MySecondSubscription" "MySecondResourceGroup" "MyAwesomeProject2" "DEV.settings.json"
deployInstance $zipPath "MyThirdSubscription" "MyThirdResourceGroup" "MyAwesomeProject3" "DEV.settings.json"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and so on and so forth. I think you got the idea.&lt;/p&gt;

&lt;p&gt;This should cover all the basic steps to deploy your code to Azure from your machine. Most of these scripts can be adapted quite easily to be executed on Azure DevOps. And that should be, ultimately, your goal: don't let this task sit on you for too long! They will create unnecessary clutter and noise, distracting from the real project!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cloud</category>
      <category>cicd</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Event Sourcing on Azure</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Tue, 24 Nov 2020 15:07:18 +0000</pubDate>
      <link>https://dev.to/mizrael/event-sourcing-on-azure-15ll</link>
      <guid>https://dev.to/mizrael/event-sourcing-on-azure-15ll</guid>
      <description>&lt;p&gt;Hi All! With this post, we'll start a new Series about Event Sourcing on Azure. We're going to talk a bit about the pattern, general architecture, and the individual building blocks. Then in the next posts, we'll dig more and see each one in detail.&lt;/p&gt;

&lt;p&gt;If you're a regular reader of this blog, you might know that I wrote already about Event Sourcing &lt;a href="https://www.davideguida.com/event-sourcing-in-net-core-part-1-a-gentle-introduction/?swcfpc=1" rel="noopener noreferrer"&gt;in the past&lt;/a&gt;. It's a complex pattern, probably one of the most complex to get right. I enjoy the challenges it gives and how it causes a whole plethora of other patterns to be evaluated in conjunction (&lt;a href="https://www.davideguida.com/lets-do-some-ddd-with-entity-framework-core-3-part-3-better-value-objects/?swcfpc=1" rel="noopener noreferrer"&gt;CQRS&lt;/a&gt; anyone?).&lt;/p&gt;

&lt;h4&gt;
  
  
  And like any other pattern, there are no &lt;em&gt;silver bullets&lt;/em&gt;. Architecture and implementation will change based on the Domain needs.
&lt;/h4&gt;

&lt;p&gt;But we can "quickly" lay out the general idea, and then diverge from it based on our necessities (or should I say the &lt;strong&gt;business&lt;/strong&gt; necessities).&lt;/p&gt;

&lt;p&gt;So let's start with the architecture!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i1.wp.com/www.davideguida.com/wp-content/uploads/2020/08/image-3.png?ssl=1&amp;amp;swcfpc=1" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi1.wp.com%2Fwww.davideguida.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage-3.png%3Fresize%3D788%252C392%26ssl%3D1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the left we have the Commands (or &lt;em&gt;Write Side&lt;/em&gt;), let's begin with that. The Commands our system exposes will be accessed via REST endpoints through a Web API. We could use Azure Functions with an HTTP trigger as well, but we'll talk more about this in another post of the Series.&lt;/p&gt;

&lt;p&gt;Whatever way we pick to communicate with the outer world, the commands will first go through a validation phase against the business rules. This usually happens by re-hydrating the &lt;a href="https://docs.microsoft.com/en-us/archive/msdn-magazine/2011/november/the-cutting-edge-design-of-a-domain-model?WT.mc_id=DOP-MVP-5003878#customer-as-an-aggregate-root-class" rel="noopener noreferrer"&gt;&lt;em&gt;Aggregate&lt;/em&gt; &lt;em&gt;Root&lt;/em&gt;&lt;/a&gt; from past events and performing a set of operations on it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Then, if everything is fine, the commands be translated into &lt;em&gt;Domain Events&lt;/em&gt; and persisted in our Event Store. We will be using CosmosDB for this.
&lt;/h4&gt;

&lt;p&gt;Then we have to publish &lt;em&gt;Integration Events&lt;/em&gt; to inform other parts of the system that "something" happened. This will be handled by &lt;a href="https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview?WT.mc_id=DOP-MVP-5003878#topics" rel="noopener noreferrer"&gt;Azure Service Bus Topics&lt;/a&gt;. We'll use Topics instead of simple Queues because we might have different consumer types interested in a particular event type. And of course, we want to deploy, operate, and scale those consumers independently.&lt;/p&gt;

&lt;p&gt;One of these consumers will be an Azure Functions App with a very important role: &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/materialized-view?WT.mc_id=DOP-MVP-5003878" rel="noopener noreferrer"&gt;materializing our Query Models&lt;/a&gt;. When querying data, we can't, of course, rehydrate the Aggregates each time. Yes, we would get consistent data each time, but it would be overkill, even if we were using &lt;em&gt;snapshots&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So we subscribe to the Topics and each time we receive an event, we refresh a query-specific version of the data and we store it in another storage. We will still be using CosmosDB in our example.&lt;/p&gt;

&lt;p&gt;Materialized views have the great benefit of being exactly what our calling application needs, including all the possible aggregated data. Moreover, in case our requirements change, we can always add new views or update the existing ones. As long as we have the original events stream, we can flush all the views and rebuild them from scratch with little cost.&lt;/p&gt;

&lt;p&gt;That's all for today. &lt;a href="https://www.davideguida.com/event-sourcing-on-azure-part-2-events-persistence/?swcfpc=1" rel="noopener noreferrer"&gt;Next time&lt;/a&gt; we'll see how we can handle events persistence. Ciao!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>architecture</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Blazor and Dragons! How to Consume gRPC-web From Blazor</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Tue, 14 Jul 2020 13:43:30 +0000</pubDate>
      <link>https://dev.to/mizrael/blazor-and-dragons-how-to-consume-grpc-web-from-blazor-5d59</link>
      <guid>https://dev.to/mizrael/blazor-and-dragons-how-to-consume-grpc-web-from-blazor-5d59</guid>
      <description>&lt;p&gt;Hi All! Today we’re going to talk about how to consume a gRPC service from a Blazor client. And we’re going to do it with &lt;a href="https://dnd.wizards.com/dungeons-and-dragons/what-is-dd"&gt;Dungeons &amp;amp; Dragons&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;People who know me, know that deep down, I’m a big nerd. I started playing D&amp;amp;D when I was a freshman in college and kept going for years. Eventually, I began writing my own campaigns, holding sessions as Dungeon Master, and even participating in competitions. And winning.&lt;/p&gt;

&lt;p&gt;I play &lt;a href="https://store.steampowered.com/app/257350/Baldurs_Gate_II_Enhanced_Edition/"&gt;Baldur’s Gate 2&lt;/a&gt; at least once a year. Each time with a different class/race. Oh boy, that game is massive!&lt;/p&gt;

&lt;p&gt;The last game I bought on Steam? &lt;a href="https://store.steampowered.com/app/321800/Icewind_Dale_Enhanced_Edition/"&gt;Icewind Dale&lt;/a&gt;. Of course, I played it in the past but never had the pleasure of “owning” it.&lt;/p&gt;

&lt;p&gt;So what does all of this with Blazor and gRPC? Well, a few days ago I was looking for a fun way to study them both. And I thought: is there anything out in the interwebz that I can leverage? &lt;/p&gt;

&lt;p&gt;And the answer, of course, was yes: the &lt;a href="https://www.dnd5eapi.co/"&gt;D&amp;amp;D 5e REST API&lt;/a&gt;! It’s free and doesn’t require any auth so it’s a perfect way to feed some data in our app.&lt;/p&gt;

&lt;h3&gt;
  
  
  My goal? Well as I said, I just wanted to play with Blazor and gRPC. And have some fun in the meantime.
&lt;/h3&gt;

&lt;p&gt;So I wrote a simple &lt;a href="https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-now-available/"&gt;Blazor webassembly&lt;/a&gt; gRPC client to display an archive of D&amp;amp;D classes. You can click on a row and get redirected to a detail page. Easy peasy.&lt;/p&gt;

&lt;p&gt;The data is coming from a separate application, exposing a gRPC service. This server is basically just a simple proxy over the D&amp;amp;D REST API. I deliberately decided to not add any caching or other fancy things, just to focus on the transport.&lt;/p&gt;

&lt;p&gt;Now, due to browser limitations, we can’t really use gRPC here, but we can rely on gRPC-web instead. Let me quote &lt;a href="http://james.newtonking.com/bio"&gt;James Newton-King&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is impossible to implement the gRPC HTTP/2 spec in the browser because there is no browser API with enough fine-grained control over HTTP requests. gRPC-Web solves this problem by being compatible with HTTP/1.1 and HTTP/2.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For those interested, the full article is &lt;a href="https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cL5yYzBo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dzone.com/storage/temp/13673575-1593198470826.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cL5yYzBo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dzone.com/storage/temp/13673575-1593198470826.png" alt="Yes, before you say it, I’m not good at naming things."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As usual, the code is &lt;a href="https://github.com/mizrael/BlazorAndDragons"&gt;available on GitHub&lt;/a&gt;, help yourself.&lt;/p&gt;

&lt;p&gt;Let’s explore the client today. The first step is to add our &lt;a href="https://github.com/mizrael/BlazorAndDragons/blob/master/BlazorAndDragons.Client/Protos/classes.proto"&gt;.proto file&lt;/a&gt;, defining the layout of our messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syntax = "proto3";
import "google/protobuf/empty.proto";
option csharp_namespace = "BlazorAndDragons.Client";

package classes;

service Classes {
    rpc GetAll (google.protobuf.Empty) returns (GetAllResponse);
    rpc GetDetails(GetDetailsRequest) returns (GetDetailsResponse);
}

message GetAllResponse {
    message ClassArchiveItem{
        string id = 1;
        string name = 2;
    } 

    repeated ClassArchiveItem data = 1;
}

message GetDetailsRequest{
    string id = 1;
}

message GetDetailsResponse{
    string id=1;
    string name=2;
    int32 hitDie=3;
    repeated Proficiency proficiencies=4;

    message Proficiency{
        string name=1;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not much to say here. We have two methods, one returning all the available classes (and taking no parameter: thank you &lt;a href="https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Empty"&gt;&lt;em&gt;google.protobuf.Empty&lt;/em&gt;&lt;/a&gt; ). The other one instead returns the class details given the id.&lt;/p&gt;

&lt;p&gt;Notice how I’ve leveraged the repeated keyword to define arrays of complex objects.&lt;/p&gt;

&lt;p&gt;Now, an extremely important step is to make sure our .proto definition is properly referenced in our &lt;a href="https://github.com/mizrael/BlazorAndDragons/blob/master/BlazorAndDragons.Client/BlazorAndDragons.Client.csproj"&gt;.csproj file&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ItemGroup&amp;gt;
    &amp;lt;Protobuf Include="Protos\classes.proto" GrpcServices="Client" /&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That GrpcServices=”Client” will basically tell Visual Studio to generate the client proxy classes for us. Quite handy indeed.&lt;/p&gt;

&lt;p&gt;Now we have to plug the client in our DI container in our &lt;a href="https://github.com/mizrael/BlazorAndDragons/blob/master/BlazorAndDragons.Client/Program.cs"&gt;Program.cs&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebAssemblyHostBuilder.CreateDefault(args);           
builder.Services.AddSingleton(sp =&amp;gt;
{
    var config = sp.GetRequiredService&amp;lt;IConfiguration&amp;gt;();
    var serverUrl = config["ServerUrl"];
    var channel = GrpcChannel.ForAddress(serverUrl, new GrpcChannelOptions
                {
                    HttpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler())
                });
    var client = new Classes.ClassesClient(channel);
    return client;
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, I’m using &lt;em&gt;GrpcWebMode.GrpcWeb&lt;/em&gt; here. I’m not doing any streaming, just unary calls so no need to use &lt;em&gt;GrpcWebMode.GrpcWebText&lt;/em&gt;. This gives me the benefit of smaller messages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DgebLY5I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dzone.com/storage/temp/13673579-1593198586659.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DgebLY5I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dzone.com/storage/temp/13673579-1593198586659.png" alt="*GrpcWebMode.GrpcWeb*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HcTldupc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dzone.com/storage/temp/13673580-1593198605189.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HcTldupc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dzone.com/storage/temp/13673580-1593198605189.png" alt="*GrpcWebMode.GrpcText*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those interested, &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/grpc/client?view=aspnetcore-3.1#make-grpc-calls"&gt;here’s a nice article&lt;/a&gt; explaining the difference between unary and streamed calls.&lt;/p&gt;

&lt;p&gt;Now the last step: let’s call our service! That’s actually the &lt;a href="https://github.com/mizrael/BlazorAndDragons/blob/master/BlazorAndDragons.Client/Pages/Index.razor"&gt;easy part&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@page "/"
@using Google.Protobuf.WellKnownTypes
@inject Classes.ClassesClient Client

&amp;lt;h1&amp;gt;Classes&amp;lt;/h1&amp;gt;

@if (_classes == null)
{
    &amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Loading...&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;
}
else
{
    &amp;lt;table class="table"&amp;gt;
        &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
            &amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;
            @foreach (var item in _classes)
            {
                &amp;lt;tr&amp;gt;
                    &amp;lt;td&amp;gt;&amp;lt;a href="/class/@item.Id"&amp;gt;@item.Name&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
            }
        &amp;lt;/tbody&amp;gt;
    &amp;lt;/table&amp;gt;
}
@code {
    private GetAllResponse.Types.ClassArchiveItem[] _classes;
    protected override async Task OnInitializedAsync()
    {
        var results = await this.Client.GetAllAsync(new Empty());
        this._classes = results?.Data?.ToArray();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the Client is injected and invoked during page initialization. Stop. No strings attached. Told you t’was easy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.davideguida.com/blazordragons-how-to-consume-grpc-web-from-blazor-part-2-the-server/"&gt;In another article&lt;/a&gt; we’ll take a look at our server instead. Thanks for reading!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>api</category>
      <category>grpc</category>
      <category>blazor</category>
    </item>
    <item>
      <title>Conway’s Game of Life with Blazor</title>
      <dc:creator>David Guida</dc:creator>
      <pubDate>Wed, 10 Jun 2020 19:51:51 +0000</pubDate>
      <link>https://dev.to/mizrael/conway-s-game-of-life-with-blazor-3jcj</link>
      <guid>https://dev.to/mizrael/conway-s-game-of-life-with-blazor-3jcj</guid>
      <description>&lt;p&gt;Hi All! In this article, we’re going to see an easy way to implement &lt;a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life"&gt;Conway’s Game of Life&lt;/a&gt; using &lt;a href="https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor"&gt;Blazor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ve been spending some time these days working with Blazor. It’s quite an interesting technology, and definitely an excellent alternative to Angular or React or WhateverFancyLibraryJs kids are using these days.&lt;/p&gt;

&lt;p&gt;Blazor’s has a lot of nice features and there are few good reasons why could be a good technology to adapt:&lt;/p&gt;

&lt;p&gt;model classes can be shared between client and server. No need to write them twice&lt;br&gt;
very low learning curve (if you know already .NET and possibly a bit of Razor)&lt;br&gt;
it’s an open source project, there’s a big community and the documentation is growing as we speak&lt;br&gt;
I’m using it for one of my personal night-time projects and frankly, I’m quite happy. It’s easy to use, performances are good and there’s a nice support for DI, which makes code a lot cleaner.&lt;/p&gt;

&lt;p&gt;Moreover, the fact that I can keep my entire codebase in C#, makes me way more comfortable and speeds up the development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anyways, a few days ago I learned (a bit late, yes) that John Conway passed away from COVID-19 complications.
&lt;/h3&gt;

&lt;p&gt;For those who don’t know, Conway was one of the most famous mathematicians, active in fields like number theory and combinatorial game theory.&lt;/p&gt;

&lt;p&gt;He was also the inventor of a lot of funny math riddles, like the &lt;a href="https://wordplay.blogs.nytimes.com/2015/08/10/feiveson-1/"&gt;Wizard’s age puzzle&lt;/a&gt;, and the famous cellular automaton Game of Life.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mm4G4y35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/e/e5/Gospers_glider_gun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mm4G4y35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/e/e5/Gospers_glider_gun.gif" alt="Game of Life – courtesy of Wikipedia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s an interesting simulation, with incredibly simple rules. Straight from Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any live cell with fewer than two live neighbours dies, as if by underpopulation.&lt;/li&gt;
&lt;li&gt;Any live cell with two or three live neighbours lives on to the next generation.&lt;/li&gt;
&lt;li&gt;Any live cell with more than three live neighbours dies, as if by overpopulation.&lt;/li&gt;
&lt;li&gt;Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s not super complex to code and it’s a good exercise for those interested in 2D graphics. It’s actually one of the first things I coded for Windows Phone, replying to &lt;a href="http://www.shawnhargreaves.com/blog/is-spritebatch-turing-complete.html"&gt;an article by Shawn Hargreaves&lt;/a&gt; in 2012 (phew!).&lt;/p&gt;

&lt;p&gt;The code is as usual available on &lt;a href="https://github.com/mizrael/ConwayBlazor"&gt;GitHub&lt;/a&gt;. The gist of it is in the &lt;a href="https://github.com/mizrael/ConwayBlazor/blob/master/ConwayBlazor/Models/World.cs"&gt;World&lt;/a&gt; class.&lt;/p&gt;

&lt;p&gt;The idea is to initialize two grids of booleans and swap them at each iteration. The current grid holds the state that will be used for rendering. Each update step will loop over the cells and compute the new state based on its neighbours. This will then set as the new value in the corresponding cell of the other grid.&lt;/p&gt;

&lt;p&gt;And voilà, our simulation is complete!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>blazor</category>
    </item>
  </channel>
</rss>
