<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Just a blog]]></title><description><![CDATA[Software Engineering discussions. ]]></description><link>https://mykkon.work/</link><image><url>https://mykkon.work/favicon.png</url><title>Just a blog</title><link>https://mykkon.work/</link></image><generator>Ghost 3.0</generator><lastBuildDate>Thu, 09 Apr 2026 15:03:58 GMT</lastBuildDate><atom:link href="https://mykkon.work/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Plan before you do]]></title><description><![CDATA[It's important in software engineering to build a reliable and solid system. With all the agile microservices hype it's essential to understand what you do.]]></description><link>https://mykkon.work/plan-before-you-do/</link><guid isPermaLink="false">5ee7388d76ff2f46053e2fc2</guid><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Sat, 15 Jul 2023 16:27:24 GMT</pubDate><media:content url="https://mykkon.work/content/images/2023/07/DSC03960.ARW.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://mykkon.work/content/images/2023/07/DSC03960.ARW.jpg" alt="Plan before you do"><p>.NET Core has been ported to UNIX-like systems a while ago. Some projects have started migrating to it, some started from scratch with it. This article will describe the pitfalls based on my professional experience related to micro/nano/service hype.</p><ul><li><strong>What's wrong with microservices?</strong></li><li><strong>Would my startup microservice system succeed?</strong></li><li><strong>Can I be sure that in the end the system is operational?</strong></li></ul><p>The answer for all of the above - it depends. And depends on several important things that usually people don't like to dive too deep into. </p><p>The first thing is - <strong>microservices require waterfall planning</strong>. That might sound terrifying, especially with all of the hype around Agile but believe me - if you don't know how the system with 20+ micro systems will work together you'll end up with spaghetti microservices. They'll be communicating through HTTP to keep it simple, they will depend on each other, and if you will be lucky enough - you'll end up with not really reliable but working from time to time system that can handle not that much load as you would expect from <em>microservices</em>.</p><p>Why does it like this? <br>- Lack of planning and technical clarifying at the beginning.<br>- Lack of  planning across teams during development.<br>- Lack of understaning how the system will work at the end.</p><p>The system must be incredibly clarified before you do the microservice approach from scratch. That's it. Continuous technical grooming across the all teams in several domains is a key. </p>]]></content:encoded></item><item><title><![CDATA[How to organize environment secrets with docker-compose and Visual Studio]]></title><description><![CDATA[Database passwords, local paths, environment variables - how to combine and make them work?]]></description><link>https://mykkon.work/organize-environment-variables/</link><guid isPermaLink="false">5f7ae6c876ff2f46053e3451</guid><category><![CDATA[.net]]></category><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Mon, 05 Oct 2020 16:30:00 GMT</pubDate><content:encoded><![CDATA[<p>In recent times I faced the question - how would I set up my development secrets like database passwords, connection strings, sensitive secret data without exposing them to the public world/git?</p><p>Visual Studio has a pretty nice feature to organize development secrets named <a href="https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&amp;tabs=windows#secret-manager">User Secrets</a>. Despite finding it useful to set up some of the <code>appsettings.json</code> substitutions, it's nearly useless when it comes to environment variable configuration used in <code>docker-compose</code>.</p><p>I tried several strange things like creating a bash script to populate envs from secrets.json, or adding docker arguments to .dcproj. It took me so long to make a working solution, and it was so dirty, so I end up using<br> <code>env_file</code> <a href="https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option">docker-compose configuration</a> alongside with hiding the file from git.</p><pre><code class="language-YAML">services:
  data:
    image: mongo:4.4.1-bionic
    restart: always
    ports:
    - "27017:27017"
    env_file:
    - .env # placed in the same folder as docker-compose.yml</code></pre><p></p><p>And <code>.env</code> file is just a plain text with environment variables you need as a <br>&lt;key&gt;=&lt;value&gt; pair:</p><pre><code class="language-TEXT">MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=************************
</code></pre><p></p><p>And don't forget to add <code>.env</code> to your <code>.gitignore</code> file.</p><pre><code class="language-GIT">@@ -9,6 +9,7 @@
 *.user
 *.userosscache
 *.sln.docstates
+*.env

 # User-specific files (MonoDevelop/Xamarin Studio)
 *.userprefs</code></pre><p></p><p>(OPTIONAL) I also find it useful to have a reference in my Visual Studio project to that file so I can edit it on demand.</p><pre><code class="language-XML">&lt;ItemGroup&gt;
  &lt;Content Include="..\.env" LinkBase="envs" /&gt;
&lt;/ItemGroup&gt;</code></pre>]]></content:encoded></item><item><title><![CDATA[Understanding async/await State Machine in .NET]]></title><description><![CDATA[.NET async/await syntactic sugar behind the scenes. ]]></description><link>https://mykkon.work/async-state-machine/</link><guid isPermaLink="false">5f1eed1c76ff2f46053e303e</guid><category><![CDATA[.net]]></category><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Tue, 04 Aug 2020 06:32:08 GMT</pubDate><media:content url="https://mykkon.work/content/images/2020/08/DSC08544.ARW.jpg" medium="image"/><content:encoded><![CDATA[<h1 id="intro">Intro</h1><img src="https://mykkon.work/content/images/2020/08/DSC08544.ARW.jpg" alt="Understanding async/await State Machine in .NET"><p>I'm used to be using async/await keywords in .NET. It increases the throughput of the services I'm working on dramatically.  At some point, using async gained me 10x performance improvements in terms of users throughput, by simply applying asynchronous overload to the critical part of a software. But if it's so simple to use and at the same time so powerful - how does it work behind the scenes? Well, not that simple. The keywords I love so much for their simplicity are just syntactic sugar and translated on a compiler level to something called <strong>Async</strong> <strong>State Machine</strong>. </p><h1 id="example">Example</h1><p>Let's dive a bit deeper and rely on an example. I will use simple program that tries to get the data from<br> <code>Dictionary</code> if the key is found, if not I <code>await</code> with<br> <code>Task.Delay</code> and after that initializing it for later use.</p><p>That's how I see the code in IDE:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">private readonly Dictionary&lt;string, decimal&gt; _dictionaryCache = new Dictionary&lt;string, decimal&gt;();

public Task&lt;decimal&gt; GetValueFromCacheAsync(string key)
{
    if(_dictionaryCache.ContainsKey(key))
    {
        return Task.FromResult(_dictionaryCache[key]);
    }

    return InitCacheLazyAsync(key);
}

private async Task&lt;decimal&gt; InitCacheLazyAsync(string key)
{
    await Task.Delay(1000);
    var value = 11.11m;

    _dictionaryCache.Add(key, value);

    return value;
}</code></pre><figcaption>Dummy cache class</figcaption></figure><p>And that's what the code looks like on a compiler level:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

class StateMachineCompiler
{
    public Task&lt;decimal&gt; GetValueFromCacheAsync(string key)
    {
        return _dictionaryCache.ContainsKey(key) ? Task.FromResult(_dictionaryCache[key]) : InitCacheLazyAsync(key);
    }

    private Task&lt;decimal&gt; InitCacheLazyAsync(string key)
    {
        var stateMachine = new InitCacheLazyStateMachine();
        stateMachine.RelatedTo = this;
        stateMachine.Builder = AsyncTaskMethodBuilder&lt;decimal&gt;.Create();
        stateMachine.State = State.Created;
        stateMachine.Key = key;
        stateMachine.Builder.Start(ref stateMachine);

        return stateMachine.Builder.Task;
    }

    private struct InitCacheLazyStateMachine : IAsyncStateMachine
    {
        public State State;
        public AsyncTaskMethodBuilder&lt;decimal&gt; Builder;
        public string Key;
        public StateMachineCompiler RelatedTo;
        private TaskAwaiter _taskAwaiter;

        // Task state management.
        void IAsyncStateMachine.MoveNext()
        {
            // ...
        }
    }

    enum State 
    {
        //...
    }
}</code></pre><figcaption>Compiler generated code</figcaption></figure><p>Wow! No more async await keywords in our code, but does it mean we're running synchronous code? As always in software engineering it depends on a context.</p><p>By default .NET runtime will try to execute the Task straight away if it could - synchronously. The reason for that is to not overhead with queuing and scheduling management if the code is actually can perform synchronously. But even on synchronous method marked with async (without await inside) state machine will be generated anyway and the code which could potentially be inlined and executed much faster will be generating additional complexity for state machine management. <strong>That's why it's so important to mark methods as async if and only if there is await inside</strong>. </p><p>So let's take a closer look at State Machine compiler generated contract:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public interface IAsyncStateMachine
{
    //
    // Summary:
    //     Moves the state machine to its next state.
    void MoveNext();
    //
    // Summary:
    //     Configures the state machine with a heap-allocated replica.
    //
    // Parameters:
    //   stateMachine:
    //     The heap-allocated replica.
    void SetStateMachine(IAsyncStateMachine stateMachine);
}</code></pre><figcaption>IAsyncStateMachine</figcaption></figure><p>The main method state machine operates on is<br> <code>void MoveNext();</code> An interesting part that it returns nothing because mutates the state by reference. By design it's relying on awaiters completion and what it actually does is well described in docs:<br> <code>Moves the state machine to its next state.</code></p><p><code>StateMachine</code> itself may have three different states to track Task status:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">enum State
{
    Completed = -2,
    Created = -1,
    Awaiting = 0,
}</code></pre><figcaption>By default state machine has no enum inside but only integer flags. The enum is translated on my best guess.</figcaption></figure><p>Once <code>AsyncTaskMethodBuilder</code> hits Start command state machine's <br><code>MoveNext</code> method is being executed. </p><p>What <code>MoveNext</code> does is state management, it checks if awaiter is completed or not and changes the state of state machine and/or Task. Once state machine is finally able to mark the task as completed it calls<br> <code>Builder.SetResult();</code> and it's done.</p><p>Here is a basic flow for this example:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://mykkon.work/content/images/2020/07/StateMachine.png" class="kg-image" alt="Understanding async/await State Machine in .NET"><figcaption>State machine flowchart</figcaption></figure><p><code>GetValueFromCacheAsync</code> is now initializing state machine <strong>(2) </strong>and starts Task processing/scheduling <strong>(3) </strong>for the first time.</p><p>Once task processing's being started the runtime checks if task can be executed synchronously and if so Task.ExecuteEntry is called, Task is marked as completed, and we got the task fulfilled with result straight away. <br>If the task can't run synchronously - that's where by default ThreadPool queuing comes in play.</p><p>ThreadPool queuing operates on events and callbacks as well as asynchronous operations. There are two types of processing - CPU bound and I/O bound. On truly asynchronous operations such as writing to Disk or making Network requests .NET waits to be notified that native process is completed and assigns a thread to continue processing the result of a native service. That's what called I/O bound operations. For CPU bound there could be a thread to process the result in a background. For a better understanding of how this is possible I recommend to read <a href="https://blog.stephencleary.com/2013/11/there-is-no-thread.html">article by Stephen Cleary - there is no thread</a>. </p><p>So once ThreadPool is notified about completion of asynchronous operation it notifies <strong>Async State Machine </strong>again and <code>MoveNext()</code> is executed second time. </p><p><code>MoveNext</code> checks if awaiter is completed and since it is - sets the result of the task and it's done. The state machine exits and .NET continue processing.</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">private struct InitCacheLazyStateMachine : IAsyncStateMachine
{
    public State State;

    public AsyncTaskMethodBuilder&lt;decimal&gt; Builder;

    public string Key;

    public StateMachineCompiler RelatedTo;

    private TaskAwaiter _taskAwaiter;

    public void SetStateMachine(IAsyncStateMachine stateMachine)
    {
        // Obsolete contract.
    }

    void IAsyncStateMachine.MoveNext()
    {
        State currentState = State;
        decimal result;
        try
        {
            TaskAwaiter awaiter;
            if (currentState != State.Awaiting)
            {
                awaiter = Task.Delay(1000).GetAwaiter();
                if (!awaiter.IsCompleted)
                {
                    State = State.Awaiting;
                    _taskAwaiter = awaiter;
                    var stateMachine = this;

                    // Schedules the state machine to proceed to the next action when the specified awaiter completes.
                    Builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);

                    return;
                }
            }
            else
            {
                awaiter = _taskAwaiter;
                _taskAwaiter = new TaskAwaiter();
                State = State.Created;
            }

            awaiter.GetResult();
            result = new decimal(1111, 0, 0, false, 2);
            RelatedTo._dictionaryCache.Add(Key, result);
        }
        catch (Exception ex)
        {
            State = State.Completed;
            Builder.SetException(ex);

            return;
        }

        State = State.Completed;
        Builder.SetResult(result);
    }
}</code></pre><figcaption>State Machine MoveNext()</figcaption></figure><h1 id="conclusion">Conclusion</h1><ul><li>Do not mark methods async if there is no await inside.</li><li>The code we write so tidy and clean could be a mess behind the scenes - it's always good to strive for knowledge and understand the underlying complexity of a software.</li></ul><p>I haven't touched in this article error handling parts as well as I didn't want to dive too deeply inside. I may touch it in my future posts, though.<br>Please feel free to join the discussion or give me a heads up on any part you're interested in.</p><h1 id="references-">References:</h1><ol><li>TaskScheduler <code>QueueTask</code> <a href="https://github.com/dotnet/runtime/blob/b5705587347d29d79cec830dc22b389e1ad9a9e0/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs#L42">GitHub link</a></li><li>Task <code>ExecuteEntry</code> <a href="https://github.com/dotnet/runtime/blob/b5705587347d29d79cec830dc22b389e1ad9a9e0/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs#L2210">GitHub link</a></li><li><a href="https://blog.stephencleary.com/2013/11/there-is-no-thread.html">There is no thread</a></li></ol>]]></content:encoded></item><item><title><![CDATA[Flutter, ReactNative, NativeScript]]></title><description><![CDATA[Which framework to choose for your pet Android project development]]></description><link>https://mykkon.work/flutter-reactnative-nativescript/</link><guid isPermaLink="false">5ec7c46076ff2f46053e2e70</guid><category><![CDATA[android]]></category><category><![CDATA[flutter]]></category><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Fri, 22 May 2020 16:15:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1541345023926-55d6e0853f4b?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<h3 id="tl-dr">TL;DR</h3><img src="https://images.unsplash.com/photo-1541345023926-55d6e0853f4b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=2000&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Flutter, ReactNative, NativeScript"><p>Choose <a href="https://flutter.dev/">Flutter</a></p><h3 id="disclaimer">Disclaimer</h3><p>Information in this post is just my personal feelings which could be different from yours.</p><h2 id="compare-frameworks">Compare frameworks</h2><p>I never was an Android developer but from time to time I tried to create some apps for my mobile phone. I tried several frameworks and technologies: Xamarin, Nativescript, React Native, and finally Flutter. What I can say - the fastest boost for me as a newcomer was indeed in Flutter. The <a href="https://github.com/flutter/flutter">community</a> is so big (93k stars on GitHub at the moment) so you can get almost anything you need out of community for your Android application. </p><p>For example I required my app a calendar to show the events based on the dates. With the Flutter community that was the smoothest process I could even imagine - there are several great calendar widgets on GitHub completely open-source and free, nevertheless, very powerful and customizable. So I'm a complete rookie on the Dart/Flutter development was able to complete a calendar feature in a matter of time (a few hours to be honest). </p><p>Check the following community list:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/Solido/awesome-flutter"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Solido/awesome-flutter</div><div class="kg-bookmark-description">An awesome list that curates the best Flutter libraries, tools, tutorials, articles and more. - Solido/awesome-flutter</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/favicons/favicon.svg" alt="Flutter, ReactNative, NativeScript"><span class="kg-bookmark-author">Solido</span><span class="kg-bookmark-publisher">GitHub</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://repository-images.githubusercontent.com/90528830/018a6400-d879-11e9-92b4-492c61d9bc32" alt="Flutter, ReactNative, NativeScript"></div></a></figure><p>I tried to do the same with Xamarin, React Native or NativeScript - unfortunately only React Native is outstanding with its community and perhaps it's just my feeling but there are no that much good and customizable components for the others. </p><p>Xamarin has XML structured code style for UI which for me is very painful to develop, no hot reload, debug of components isn't easy, MVVM approach is just a mess. IMO it's the worst thing I've ever tried.</p><p>NativeScript is cool if you have some experience with Angular but again it's not so widely popular so you can have some difficulties finding a component out of community.</p><p>So let's take a look at Flutter vs React Native:<br>I'd prefer Flutter for its Dart language which is strongly typed out of the box and for its strong relation to Material Design guidelines. The way both of the frameworks are structured is almost the same - you're writing UI, styles, and logic in the same files, arranging the components as they will appear on the UI and adding callbacks. The difference comes in the development environment - Flutter has outstanding extensions for VS Code though I was able to quickly and painlessly debug my app, check the components in runtime or even make some performance profiling! Also worth mentioning that Flutter is great at resolving dependencies through <a href="https://pub.dev/">pub.dev</a> and has clean and intelligible <br><code>pubspec.yaml</code> where you can customize the app.</p><p>The main point of success of the framework as for me is how far I can go in development and how many difficulties I'll be facing during the process. Flutter is easy and powerful so if you just as I didn't have a chance to touch it you'll be able to get up to speed in several days. Also if for some reason you need to dive deeper you can succeed in that due to such a great community that you'll definately find good and useful during the development.</p>]]></content:encoded></item><item><title><![CDATA[Override or extend Swashbuckle Swagger UI]]></title><description><![CDATA[In this article we'll try to figure out how to extend or override regular swagger ui with custom HTML or javascript]]></description><link>https://mykkon.work/override-swashbuckle-swagger/</link><guid isPermaLink="false">5ddb98e03392494604a83285</guid><category><![CDATA[swagger]]></category><category><![CDATA[.net]]></category><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Mon, 25 Nov 2019 18:10:00 GMT</pubDate><content:encoded><![CDATA[<p>There are several use cases for swagger ui to be overriden:</p><ul><li><strong>Add custom HTML to swagger</strong></li><li><strong>Add custom header to swagger requests</strong></li><li><strong>Update or extend authorization</strong></li></ul><p>In <a href="https://github.com/domaindrivendev/Swashbuckle">Swashbuckle</a> there is a way to inject custom javascript and css into the body:</p><figure class="kg-card kg-code-card"><pre><code class="language-csharp">public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	app.UseSwaggerUI(c =&gt;
    {
        c.InjectJavascript("extend-swagger.js");
        c.InjectStylesheet("extend-swagger.css");
    });
}</code></pre><figcaption>Startup.cs</figcaption></figure><p>JS and CSS files can exist under <code>wwwroot</code> folder with <code>UseStaticFiles</code> middleware.</p><p>Then you can implement new swagger configuration in "extend-swagger.js" file:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">const ui = SwaggerUIBundle({
        url: "/swagger/v1/swagger.json",
        dom_id: '#swagger-ui',
        deepLinking: true,
        requestInterceptor: function(request) {
        	// request interceptor
            // add custom headers here
            return request;
        },
        onComplete: function() {
            // on complete callback
        }, 
        presets: [
            SwaggerUIBundle.presets.apis,
            SwaggerUIStandalonePreset
        ],
        plugins: [
            SwaggerUIBundle.plugins.DownloadUrl
        ],
        layout: "StandaloneLayout"
    });

// this is a full override of Swagger UI
window.ui = ui;  </code></pre><figcaption>wwwroot/extend-swagger.js</figcaption></figure><p>Full configuration of <em>SwaggerUIBundle </em>can be found at <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/">swagger-ui docs</a></p>]]></content:encoded></item><item><title><![CDATA[.NET Core how to add any origin to CORS and allow credentials]]></title><description><![CDATA[In this arcticle we'll try to understand how to setup AllowAnyOrigin alongside with AllowCredentials in .NET Core]]></description><link>https://mykkon.work/how-to-setup-any-origin/</link><guid isPermaLink="false">5dda353f3392494604a8322f</guid><category><![CDATA[.net]]></category><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Sun, 24 Nov 2019 08:50:00 GMT</pubDate><content:encoded><![CDATA[<p>When I was migrating from .NET Core 2.2 to 3.0 I faced with the following error:</p><!--kg-card-begin: markdown--><p><em>System.InvalidOperationException: The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the CORS policy by listing individual origins if credentials needs to be supported.</em></p>
<!--kg-card-end: markdown--><h2 id="issue">Issue</h2><p>The core issue was in the code:</p><pre><code class="language-csharp">public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddCors(options =&gt;
    {
    	options.AddDefaultPolicy(builder =&gt; builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());
    });
}</code></pre><p>Since <code>SignalR</code> actually requires <code>AllowCredentials</code> I tried to not specify exact origin for development.</p><h2 id="solution">Solution</h2><p>Here is a workaround to use both wildcard for any origin and allowing credentials:</p><pre><code class="language-csharp">public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddCors(options =&gt;
    {
    	options.AddDefaultPolicy(builder =&gt; 
            builder.SetIsOriginAllowed(_ =&gt; true)
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials());
    });
}</code></pre><!--kg-card-begin: markdown--><blockquote>
<p>Just be careful to not use that kind of code in production - you probably don't want allowing any origin to make a handshake with SignalR</p>
</blockquote>
<!--kg-card-end: markdown--><p>And here we go with these settings we won't get browser<br><code>Cross-Origin Request Blocked</code> and <strong>SignalR</strong> will make a handshake as usual.</p>]]></content:encoded></item><item><title><![CDATA[Hello World]]></title><description><![CDATA[Me describing my feelings of how easy it is to create own blog.]]></description><link>https://mykkon.work/hello-world/</link><guid isPermaLink="false">5dd99e9fe5419f413b20799a</guid><category><![CDATA[discussion]]></category><dc:creator><![CDATA[Mykhailo Konovalov]]></dc:creator><pubDate>Sat, 23 Nov 2019 21:16:54 GMT</pubDate><content:encoded><![CDATA[<p>Hello Web World! </p><pre><code class="language-csharp">public static void Main(string[] args)
{
	Console.WriteLine("Привет!");
}</code></pre><p></p><p>This is my first post on my first blog. Thanks to <a href="https://ghost.org">Ghost</a> I was able to make it fully working with one Saturday 😁 my wife isn't as happy about me spending the weekend around laptop, however, I believe I'll figure this out.</p><p>Thank you for reading this and see you soon!</p>]]></content:encoded></item></channel></rss>