<?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: Sotirios Mantziaris</title>
    <description>The latest articles on DEV Community by Sotirios Mantziaris (@mantzas).</description>
    <link>https://dev.to/mantzas</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%2F276250%2Fabffda8a-c293-4fbd-b642-57ef08736c86.png</url>
      <title>DEV Community: Sotirios Mantziaris</title>
      <link>https://dev.to/mantzas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mantzas"/>
    <language>en</language>
    <item>
      <title>Parallelize work using parwork</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:43 +0000</pubDate>
      <link>https://dev.to/mantzas/parallelize-work-using-parwork-16n4</link>
      <guid>https://dev.to/mantzas/parallelize-work-using-parwork-16n4</guid>
      <description>&lt;p&gt;In order to process a lot of work we have to parallelize work across all cores, and especially if it's CPU bound.&lt;br&gt;
Go has goroutines, which can be used to parallelize the work, but there is the cost of context switching for a lot of goroutines.&lt;br&gt;
Minimizing this context switching can be achieved by using a fork-join model when processing work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mantzas/parwork" rel="noopener noreferrer"&gt;Parwork&lt;/a&gt; solves this problem by using goroutines, channels and waitgroups. It creates workers (goroutines) that pull&lt;br&gt;
work of a queue (channel), process the work and report the work back to a queue (channel).&lt;br&gt;
This is done in a abstracted way so the user has to provide implementation for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Work interface&lt;/li&gt;
&lt;li&gt;a WorkGenerator function&lt;/li&gt;
&lt;li&gt;a WorkCollector function&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Work interface
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Work&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;GetError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
    &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The work interface defines a method &lt;code&gt;Do()&lt;/code&gt; which contains all the processing logic of the work item. The &lt;code&gt;GetError() error&lt;/code&gt; method can be used to flag the work item as failed and return a error. The &lt;code&gt;Result() interface{}&lt;/code&gt; defines a method which returns the result of the work. Due to the lack of generics the data return has to be cast from &lt;code&gt;interface{}&lt;/code&gt; to the actual result type in order to be usable in the WorkCollector.&lt;/p&gt;

&lt;p&gt;The following example work implementation shows a work item that calculates a MD5 hash of a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// md5Work defines a structure that holds the value to be hashed and the result of the hashing&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;md5Work&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;   &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;
    &lt;span class="n"&gt;hashed&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Do calculates the hash of the given value&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gw&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;md5Work&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;gw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hashed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// GetError returns nil since the work does not fail&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gw&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;md5Work&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Result returns the hashed result&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gw&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;md5Work&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;gw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the examples folder of the &lt;a href="https://github.com/mantzas/parwork" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repo for a complete example.&lt;/p&gt;

&lt;h3&gt;
  
  
  WorkGenerator function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;WorkGenerator&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;Work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WorkGenerator function allows the user to provide a implementation that returns on each call a work item to be processed. If the generator returns nil the generation of work has finished.&lt;/p&gt;

&lt;p&gt;Check out the examples folder of the &lt;a href="https://github.com/mantzas/parwork" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repo for a implementation of the generator.&lt;/p&gt;

&lt;h3&gt;
  
  
  WorkCollector function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;WorkCollector&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Work&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The WorkCollector function takes as a argument a completed Work item. It can check for a failure by calling the GetError or the Result method of the Work item and handle it appropriately.&lt;/p&gt;

&lt;p&gt;Check out the examples folder of the &lt;a href="https://github.com/mantzas/parwork" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repo for a implementation of the collector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check out
&lt;/h3&gt;

&lt;p&gt;Head over to the &lt;a href="https://github.com/mantzas/parwork" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repo to see the code, with a working example, try it and if you find something, like a bug or a improvement, don't hesitate do open a issue or better yet create a PR.&lt;/p&gt;

&lt;p&gt;Thanks and enjoy!&lt;/p&gt;

</description>
      <category>parallel</category>
      <category>go</category>
    </item>
    <item>
      <title>Various .NET Benchmarks</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:42 +0000</pubDate>
      <link>https://dev.to/mantzas/various-net-benchmarks-1lm9</link>
      <guid>https://dev.to/mantzas/various-net-benchmarks-1lm9</guid>
      <description>&lt;p&gt;A lot of times i was wondering what is the best performing code.&lt;br&gt;
In order to determine that i had to benchmark my code, but benchmarks are hard to write.&lt;br&gt;
Luckily there is a open source project that does this work perfectly good and very easy.&lt;/p&gt;

&lt;p&gt;The name of the library is BenchmarkDotNet and the documentation can be found &lt;a href="http://benchmarkdotnet.org/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
The only thing you have to do is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a console application project (.NET/.NET Core)&lt;/li&gt;
&lt;li&gt;Install the nuget BenchmarkDotNet and it's dependencies&lt;/li&gt;
&lt;li&gt;Always run in release mode!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following code is needed in the Program Main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BenchmarkSwitcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromAssembly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTypeInfo&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which will scan the assembly for benchmarks and asks you which one to run.&lt;/p&gt;

&lt;p&gt;A typical benchmark is just a class with methods that are annotated with the &lt;code&gt;[Benchmark]&lt;/code&gt; attribute like the following one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MemoryDiagnoser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateTimeToStringBenchmark&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;_dateTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;59&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;59&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Baseline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"DateTime ToString"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;DateTimeToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_dateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"DateTime ToString with format"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;DateTimeToStringFormat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_dateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"g"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple isn't it?&lt;/p&gt;

&lt;p&gt;After the run the result is the following:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Scaled&lt;/th&gt;
&lt;th&gt;ScaledSD&lt;/th&gt;
&lt;th&gt;Gen 0&lt;/th&gt;
&lt;th&gt;Gen 1&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;'DateTime ToString'&lt;/td&gt;
&lt;td&gt;848.8 ns&lt;/td&gt;
&lt;td&gt;2.8059 ns&lt;/td&gt;
&lt;td&gt;2.4874 ns&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.0410&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;132 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;'DateTime ToString with format'&lt;/td&gt;
&lt;td&gt;790.0 ns&lt;/td&gt;
&lt;td&gt;18.0956 ns&lt;/td&gt;
&lt;td&gt;16.0413 ns&lt;/td&gt;
&lt;td&gt;0.93&lt;/td&gt;
&lt;td&gt;0.02&lt;/td&gt;
&lt;td&gt;0.0391&lt;/td&gt;
&lt;td&gt;0.0104&lt;/td&gt;
&lt;td&gt;124 B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I get the timings of the method and by using the &lt;code&gt;[MemoryDiagnoser]&lt;/code&gt; attribute i get event the GC Stats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conducted Benchmarks
&lt;/h2&gt;

&lt;p&gt;Given the easiness to create such benchmark i have started a github repository named &lt;a href="https://github.com/mantzas/DotNetBenchmarks" rel="noopener noreferrer"&gt;DotNetBenchmarks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There you can find some of the performance questions that i have about some components like logging frameworks, XML Serialization, String concatenation etc.&lt;br&gt;
Every time i have to check the performance of some component i will add a new benchmark to this repository. If anyone likes to contribute, even better!&lt;br&gt;
Make a PR!&lt;/p&gt;

&lt;p&gt;Please note that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These benchmark are not conducted in order to make certain libraries look good or bad&lt;/li&gt;
&lt;li&gt;Please create a issue or better make a PR if you think that the benchmark methodology is wrong or the setup is wrong&lt;/li&gt;
&lt;li&gt;Do not take the results as granted and conduct your own benchmarks to see if in the context of your application the results differ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks and enjoy!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>New go event sourcing library named incata</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:41 +0000</pubDate>
      <link>https://dev.to/mantzas/new-go-event-sourcing-library-named-incata-5h66</link>
      <guid>https://dev.to/mantzas/new-go-event-sourcing-library-named-incata-5h66</guid>
      <description>&lt;p&gt;Event sourcing is capturing all changes of an application state as a sequence of events.&lt;br&gt;
Since we only store events we only have to add events to a store, in contrast to updates for keeping the application state.&lt;br&gt;
A much simpler model that scales very well. When needing the application state we just aggregate the events into&lt;/p&gt;

&lt;p&gt;More on this can be read all over the internet but two excellent links are available below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://martinfowler.com/eaaDev/EventSourcing.html" rel="noopener noreferrer"&gt;Martin Fowler Event Sourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.geteventstore.com/introduction/event-sourcing-basics/" rel="noopener noreferrer"&gt;Event Sourcing Basics by Event Store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The library has support for the following RDBMS's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft SQL Server&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/mantzas/incata" rel="noopener noreferrer"&gt;incata&lt;/a&gt; is very easy to setup and to use like illustrated on the github page.&lt;br&gt;
Any ideas or improvements are highly welcome. Enjoy!&lt;/p&gt;

</description>
      <category>go</category>
      <category>eventsourcing</category>
      <category>eventstore</category>
    </item>
    <item>
      <title>Initial release of adaptlog</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:40 +0000</pubDate>
      <link>https://dev.to/mantzas/initial-release-of-adaptlog-2mce</link>
      <guid>https://dev.to/mantzas/initial-release-of-adaptlog-2mce</guid>
      <description>&lt;p&gt;Almost every application logs data one way or another. There are a plethora of logging packages available for &lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;golang&lt;/a&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is the one that comes with the standard packages which takes a simple approach.
&lt;/li&gt;
&lt;li&gt;There are many logging packages that follow the well established leveled approach, and there are really a lot of them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The decision of choosing a specific library comes with the cost of a direct dependency.&lt;br&gt;
But why should we depend directly on a specific package?&lt;br&gt;
How painful is it to exchange a logging package for another when we already created a lot of code with a direct dependency?&lt;br&gt;&lt;br&gt;
This is the reason why &lt;a href="https://github.com/mantzas/adaptlog" rel="noopener noreferrer"&gt;apaptlog&lt;/a&gt; came to life.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mantzas/adaptlog" rel="noopener noreferrer"&gt;apaptlog&lt;/a&gt; is just a logging abstraction, which itself does not implement any log related stuff.&lt;br&gt;
A logger has to be provided by the developer using any of the previous mentioned logging packages or any custom implementation.&lt;br&gt;
The developer has to implement only a logging interface (standard or leveled), configure it at application start and use the abstraction throughout the code.&lt;br&gt;
This is hardly something new. There are many libraries in other languages that do exactly this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mantzas/adaptlog" rel="noopener noreferrer"&gt;apaptlog&lt;/a&gt; is very easy to setup and to use. Follow the sample for the standard logger implementation.&lt;br&gt;
Any ideas or improvements are highly welcome. Enjoy!&lt;/p&gt;

</description>
      <category>go</category>
      <category>log</category>
      <category>logging</category>
    </item>
    <item>
      <title>dotNETZone.gr meetup .NET core presentation</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:39 +0000</pubDate>
      <link>https://dev.to/mantzas/dotnetzonegr-meetup-net-core-presentation-ifj</link>
      <guid>https://dev.to/mantzas/dotnetzonegr-meetup-net-core-presentation-ifj</guid>
      <description>&lt;p&gt;The presentation was about the current state of .NET Core in the Linux World.&lt;br&gt;
Here are &lt;a href="http://go-talks.appspot.com/github.com/mantzas/presentations/20161106_shaken_to_the_dotnet_core/shaken_to_the_dotnet_core.slide#1" rel="noopener noreferrer"&gt;the slides&lt;/a&gt; of the presentation&lt;br&gt;
and the &lt;a href="https://github.com/mantzas/presentations/tree/master/20161106_shaken_to_the_dotnet_core" rel="noopener noreferrer"&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for attending.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>linux</category>
    </item>
    <item>
      <title>The Repository and Unit of Work pattern</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:38 +0000</pubDate>
      <link>https://dev.to/mantzas/the-repository-and-unit-of-work-pattern-18a4</link>
      <guid>https://dev.to/mantzas/the-repository-and-unit-of-work-pattern-18a4</guid>
      <description>&lt;p&gt;Yes, i know not this again. Is this not the one millionth time that someone blogs about that?&lt;br&gt;
Yes, yes and yes but…&lt;br&gt;
It is always good to repeat things and we all know that&lt;/p&gt;

&lt;p&gt;“Repetition is the mother of learning, the father of action, which makes it the architect of accomplishment.” ― &lt;a href="https://en.wikipedia.org/wiki/Zig_Ziglar" rel="noopener noreferrer"&gt;Zig Ziglar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are still implementations out there that might benefit from this…&lt;/p&gt;

&lt;p&gt;So let’s start with some definitions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;Quoting &lt;a href="http://martinfowler.com/eaaCatalog/repository.html" rel="noopener noreferrer"&gt;Martin Fowler’s Definition&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper (165),&lt;br&gt;
that isolates domain objects from details of the database access code. In such systems it can be worthwhile to build another layer of abstraction&lt;br&gt;
over the mapping layer where query construction code is concentrated. This becomes more important when there are a large number of domain classes or heavy querying.&lt;br&gt;
In these cases particularly, adding this layer helps minimize duplicate query logic. A Repository mediates between the domain and data mapping layers,&lt;br&gt;
acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction.&lt;br&gt;
Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository&lt;br&gt;
will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations&lt;br&gt;
performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and&lt;br&gt;
one-way dependency between the domain and data mapping layers.&lt;/p&gt;

&lt;p&gt;Reading different sources (&lt;a href="https://msdn.microsoft.com/en-us/library/ff649690.aspx" rel="noopener noreferrer"&gt;MSDN The Repository Pattern&lt;/a&gt;,&lt;br&gt;
&lt;a href="http://martinfowler.com/eaaCatalog/repository.html" rel="noopener noreferrer"&gt;Martin Fowler: Repository&lt;/a&gt; etc) about the repository pattern the following properties emerge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It maps between Domain Objects and Data objects&lt;/li&gt;
&lt;li&gt;It does not expose the data layer to the outside world&lt;/li&gt;
&lt;li&gt;It consolidates all data access patterns in one place thus help with code deduplication&lt;/li&gt;
&lt;li&gt;It has a single responsibility&lt;/li&gt;
&lt;li&gt;It is simple to implement&lt;/li&gt;
&lt;li&gt;It has a one way dependency between the domain and the data layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple example is the following application repository(C#):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IApplicationRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;DeleteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By providing an interface we can leave the implementation up top the developer to choose the data access library they wish.&lt;br&gt;
The argument and return values of this interface should be domain specific objects and not the data objects to avoid spilling the data&lt;br&gt;
into other layers and have a clean separation.&lt;/p&gt;

&lt;p&gt;By using the above i had the chance to change the underlying implementation with anything i wished to experimented with.&lt;br&gt;
First everything was EF, then Simple.Data then Dapper etc. You could even mix and match any of the above since every implementation&lt;br&gt;
in the end will use a SqlConnection. It is really easy to change the underlying implementation.&lt;/p&gt;

&lt;p&gt;You may think that changing the implementation happens not that often (migrate from EF to Dapper or from nHibernate to EF or Dapper etc)&lt;br&gt;
but it can happen and is a really cheap abstraction over your data layer implementation. It further promotes clean separation which is always something worth doing.&lt;br&gt;
This allows the application to not depend directly on the data access library and allows for future change with little cost.&lt;br&gt;
For example if you have a application that uses nHibernate, which was maybe a good choice in the past, you are missing out some things&lt;br&gt;
that other ORM provide like async calls or even the new .Net Core which may or may not happen for nHibernate. Dapper and EF already have the above.&lt;/p&gt;

&lt;p&gt;The implementation of the interface does need something in order to work with the data layer. This can be a SqlConnection, DbContext (EF), Session (NHibernate) etc.&lt;br&gt;
This will be injected to each repository and will generally be implemented in the Unit of Work.&lt;/p&gt;
&lt;h2&gt;
  
  
  Unit of Work
&lt;/h2&gt;

&lt;p&gt;Quoting &lt;a href="http://martinfowler.com/eaaCatalog/unitOfWork.html" rel="noopener noreferrer"&gt;Martin Fowler's Definition&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;A Unit of Work keeps track of everything you do during a business transaction that can affect the database.&lt;br&gt;
When you're done, it figures out everything that needs to be done to alter the database as a result of your work.&lt;/p&gt;

&lt;p&gt;So the UoW (Unit of Work) is responsible for keeping the db object (SqlConnection, DbContext) and handling the final commit in order to persist everything to DB.&lt;/p&gt;

&lt;p&gt;A simple interface (C#) that has to be implemented is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IUnitOfWork&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IApplicationRepository&lt;/span&gt; &lt;span class="n"&gt;Applications&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;CommitAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is just a wrapper around our db object (SqlConnection, DbContext etc) and the implementation of the commit.&lt;br&gt;
When we have a UoW we have at our hands all the necessary repositories, so interacting with them is really easy.&lt;/p&gt;
&lt;h2&gt;
  
  
  EF baked implementation and usage
&lt;/h2&gt;

&lt;p&gt;Now we have the the following implementation for the application repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationRepository&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDataAccess&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; 
                                        &lt;span class="n"&gt;IApplicationRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ApplicationRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; 
        &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;DeleteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeleteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SingleOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where the base repository is a EF implementation of the following interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IDataAccess&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;IQueryable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;params&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;keyValues&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;DeleteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;params&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;keyValues&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is fairly easy to implementing another data access library. A dapper implementation of the application repository has&lt;br&gt;
as constructor parameter a SqlConnection and the actual implementation of the interface methods. That’s it.&lt;/p&gt;

&lt;p&gt;The unit of work implementation is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UnitOfWork&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IUnitOfWork&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IMapper&lt;/span&gt; &lt;span class="n"&gt;_mapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;_dbContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContext&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IMapper&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_dbContext&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_mapper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CommitAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IApplicationRepository&lt;/span&gt; &lt;span class="n"&gt;Applications&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ApplicationRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_dbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_mapper&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;//Implement IDisposable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple implementation of the UoW. Do not mind that some features are missing like transaction handling&lt;br&gt;
(DbContext.Database.BeginTransaction() and then commit or rollback) a repository factory etc which are fairly easy to implement.&lt;/p&gt;

&lt;p&gt;And how is this used?&lt;/p&gt;

&lt;p&gt;Let’s assume we have a Unit Of Work Factory implemented so the code would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;uow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_unitOfWorkFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;uow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Applications&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;uow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Applications&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeleteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;uow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CommitAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy and clean, isn’t it? Everything is in one place, at the end it get’s committed and properly disposed.&lt;br&gt;
Since EF exposes the connection through the DbContext we can actually use Dapper also and have a mixed data access layer repository&lt;br&gt;
in order to handle some hotspots where EF does not play well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The repository and the unit of work patterns are fairly easy to implement. They provide a proper data access abstraction and expose only the needed domain object&lt;br&gt;
and do not spill the data object into the upper layers. The only thing needed in order to use this is to inject the unit of work factory and we have our db in our hand.&lt;br&gt;
Hope this is helpful. Any comment, discussion or fix is highly welcome.&lt;/p&gt;

</description>
      <category>repository</category>
      <category>unitofwork</category>
      <category>pattern</category>
    </item>
    <item>
      <title>Tripping the circuit</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:37 +0000</pubDate>
      <link>https://dev.to/mantzas/tripping-the-circuit-2bhi</link>
      <guid>https://dev.to/mantzas/tripping-the-circuit-2bhi</guid>
      <description>&lt;p&gt;This is probably one of the most useful "cloud" patterns out there and it is fairly easy to implement.&lt;br&gt;&lt;br&gt;
There are great articles and implementations, like &lt;a href="https://github.com/App-vNext/Polly" rel="noopener noreferrer"&gt;Polly&lt;/a&gt;,&lt;br&gt;
already on the internet about this pattern so why another one?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Κρείττον οψιμαθή είναι ή αμαθή.&lt;br&gt;&lt;br&gt;
Socrates 469-399 BC., Philosopher&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which translates to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Better too have learned lately than never, as he tried to explain why he learned to play&lt;br&gt;
guitar in his old age.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have learned better by reading, implementing and writing about something so stick with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Almost every application communicate with other services or resources, and they fail...&lt;/p&gt;

&lt;p&gt;The reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;slow network connections&lt;/li&gt;
&lt;li&gt;timeouts&lt;/li&gt;
&lt;li&gt;the resources being over-committed or temporarily unavailable&lt;/li&gt;
&lt;li&gt;buggy release&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When this happen our system becomes unstable, unreliable, brittle and failures cascade.&lt;/p&gt;

&lt;p&gt;Let's go with an example of a failing remote service, let's say we have the following scenario&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the remote service times out after 60sec&lt;/li&gt;
&lt;li&gt;our service gets 30 req/s&lt;/li&gt;
&lt;li&gt;the usual response time is 1s
&lt;/li&gt;
&lt;li&gt;each request takes up 1MB of RAM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What happens in our application?  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The current request takes up resources in order to make the call and blocks (or awaits) for 60sec&lt;/li&gt;
&lt;li&gt;All requests for the same service will suffer the same fate&lt;/li&gt;
&lt;li&gt;Almost 1800 requests will be waiting for response at the end of the first 60s&lt;/li&gt;
&lt;li&gt;Almost 1800MB of RAM is used up at the end of the first 60s&lt;/li&gt;
&lt;li&gt;All clients that call our service fail in the same way&lt;/li&gt;
&lt;li&gt;The failure cascades&lt;/li&gt;
&lt;li&gt;The response times go through the roof and will be 60s for each request due to the timeout&lt;/li&gt;
&lt;li&gt;The SLA, we might have, will be breached&lt;/li&gt;
&lt;li&gt;The perfect storm is about to form&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above is a simplified example but is not that far fetched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Using a circuit breaker can improve the stability and resilience of our application.&lt;br&gt;
The circuit is actually a state machine with 3 states&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Closed, meaning the execution will proceed&lt;/li&gt;
&lt;li&gt;Open, meaning the execution will not proceed and throw a exception or return an error (implementation specific)&lt;/li&gt;
&lt;li&gt;Half-Open, meaning that some executions are allowed after some time in order to check the remote service
and open or close the circuit based on the response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For deeper knowledge on the pattern please read the following excellent articles&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://msdn.microsoft.com/en-us/library/dn589784.aspx" rel="noopener noreferrer"&gt;MSDN Circuit Breaker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://martinfowler.com/bliki/CircuitBreaker.html" rel="noopener noreferrer"&gt;Martin Fowler Circuit Breaker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;p&gt;By using a circuit breaker we have the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fail in a controlled manner&lt;/li&gt;
&lt;li&gt;Fail fast&lt;/li&gt;
&lt;li&gt;Save server resources&lt;/li&gt;
&lt;li&gt;Maintain response times (SLA)&lt;/li&gt;
&lt;li&gt;Handle failures differently when the circuit opens eg

&lt;ul&gt;
&lt;li&gt;Redirect to another resources&lt;/li&gt;
&lt;li&gt;Save for later retry&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;There are two implementation of the circuit breaker.&lt;br&gt;
They share the same philosophy but are written in C# and Go.&lt;br&gt;
Both implementations have a setting provider interface which can be implemented&lt;br&gt;
in order to get the settings from anywhere. There is a in-memory settings implementation which&lt;br&gt;
holds the settings in memory.&lt;br&gt;
Both implementation are key based which means that for every key&lt;br&gt;
the implementation provides a separate circuit which is actually the state.&lt;br&gt;
The following setting exist for each key:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Failure Threshold at which the circuit opens&lt;/li&gt;
&lt;li&gt;Retry Timeout defines after how much time after the circuit trips will the state be half-open&lt;/li&gt;
&lt;li&gt;Retry Success Threshold defines after how many successful retries will the circuit reset and Closed&lt;/li&gt;
&lt;li&gt;Max Retry Execution Threshold defines how many retries are allowed in the half-open state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The C# implementation can be found @ &lt;a href="https://github.com/mantzas/clouddotnet" rel="noopener noreferrer"&gt;clouddotnet&lt;/a&gt;.&lt;br&gt;
The implementation is generic, asynchronous and thread safe and lock-free.&lt;br&gt;&lt;br&gt;
The Go implementation can be found @ &lt;a href="https://github.com/mantzas/gocloud" rel="noopener noreferrer"&gt;gocloud&lt;/a&gt;.&lt;br&gt;
The implementation is idiomatic and "goroutine" safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diffs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Since Go does not have generics the action to be executed returns a interface and a error
so type casting is necessary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;My &lt;a href="http://github.com/mantzas/blog" rel="noopener noreferrer"&gt;blog&lt;/a&gt; is hosted in github so for any change, improvement or fix&lt;br&gt;
you can either open a issue or submit a pull request.&lt;br&gt;&lt;br&gt;
The same goes for both implementations.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>go</category>
    </item>
    <item>
      <title>TT || !TT aka To TAP or not to TAP</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:29:36 +0000</pubDate>
      <link>https://dev.to/mantzas/tt-tt-aka-to-tap-or-not-to-tap-3957</link>
      <guid>https://dev.to/mantzas/tt-tt-aka-to-tap-or-not-to-tap-3957</guid>
      <description>&lt;p&gt;Ramblings on Tasks, async-await and ASP.NET. The &lt;a href="https://goo.gl/sO3ZGv" rel="noopener noreferrer"&gt;slides&lt;/a&gt; from the &lt;a href="http://www.meetup.com/DotNetZone/events/231198572/" rel="noopener noreferrer"&gt;meetup&lt;/a&gt;&lt;br&gt;
 do contain common issues encountered when working with TPL, async-await and ASP.NET along with some good practices. These are off course not all. Please let me know if you have any suggestions. Thanks for attenting.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>tap</category>
    </item>
    <item>
      <title>Setup a blog with Hugo and Github Pages</title>
      <dc:creator>Sotirios Mantziaris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 18:55:30 +0000</pubDate>
      <link>https://dev.to/mantzas/setup-a-blog-with-hugo-and-github-pages-57fo</link>
      <guid>https://dev.to/mantzas/setup-a-blog-with-hugo-and-github-pages-57fo</guid>
      <description>&lt;p&gt;It was long my desire to write a blog with stuff that interests me.&lt;br&gt;&lt;br&gt;
Lately i was studying &lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;Golang&lt;/a&gt; and i came across &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt; which is a really nice and fast site generation utility.&lt;br&gt;&lt;br&gt;
This was a great opportunity to start my own blog by using &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt; and &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt; in order to host it. Why?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it's free&lt;/li&gt;
&lt;li&gt;it's &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;it's easy and fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a walk through on how you can have a blog easy, fast and free! Let's start! The only thing you need is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Github Account&lt;/li&gt;
&lt;li&gt;a Domain (optional)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;p&gt;The following steps are needed for the initial setup and creation of the blog:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repository for source code of the blog&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt; repository for the generated site&lt;/li&gt;
&lt;li&gt;Setup &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create blog&lt;/li&gt;
&lt;li&gt;Publish blog to &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Generate content and publish&lt;/li&gt;
&lt;li&gt;(Optional) Setup sub domain to point to blog&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repository for source code of the blog
&lt;/h3&gt;

&lt;p&gt;Create a repository (public or private).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt; repository for the generated site
&lt;/h3&gt;

&lt;p&gt;Follow the instruction on &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt; to create a repository with your Github username. Clone it to your local drive.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Setup &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Download &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt; to your local drive. Unpack it to a folder and set the path in your OS to the executable. Almost all OS are supported!!!&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Create blog
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a folder for your blog source code and &lt;code&gt;cd&lt;/code&gt; into it.&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;hugo new site .&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add as remote repository the repository created in Step 1. (&lt;code&gt;git remote add origin https://github.com/{username}/{repository}.git&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;.gitignore&lt;/code&gt; file to exclude the path &lt;code&gt;public/&lt;/code&gt;, which is the default directory of the generated static files&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git add .&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git commit -m "initial commit"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git push -u origin master&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please refer to &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;Hugo's&lt;/a&gt; documentation for generating content, using themes etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Publish blog to &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When we are ready to deploy our blog we do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute &lt;code&gt;hugo -d {path}&lt;/code&gt;, where path is the cloned repository path from step 2&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd&lt;/code&gt; into the above path&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git add .&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git commit -m "initial commit"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;git push origin master&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After this we can enjoy our newly created blog under &lt;code&gt;http://{username}.github.io&lt;/code&gt; where username should be replaced with your &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github's&lt;/a&gt; username.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Generate content and publish
&lt;/h3&gt;

&lt;p&gt;After our initial commit we can now generate more content and publish it (Step 5).&lt;/p&gt;

&lt;h3&gt;
  
  
  7. (Optional) Setup sub domain to point to blog
&lt;/h3&gt;

&lt;p&gt;Let's assume you have a sub domain &lt;code&gt;blog.domain.com&lt;/code&gt;. The only thing you need to do is to setup a CNAME entry in your DNS configuration and point it to &lt;code&gt;{username}.github.io&lt;/code&gt;, add a file with name &lt;code&gt;CNAME&lt;/code&gt; and content &lt;code&gt;blog.domain.com&lt;/code&gt; to the root folder of the repository created in step 2, commit and you're done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;With these six (the seventh is optional) easy steps we have created a fully functional and fast blog. The cherry on top: &lt;strong&gt;for free!!!&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
(If we used public repositories in &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;). And if we assume that almost everybody nowadays has a domain it is free even with the 7th step!&lt;/p&gt;

&lt;p&gt;Happy blogging!&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>blog</category>
      <category>githubpages</category>
    </item>
  </channel>
</rss>
