<?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:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Dmitry Tikhonov on Medium]]></title>
        <description><![CDATA[Stories by Dmitry Tikhonov on Medium]]></description>
        <link>https://medium.com/@0x1000000?source=rss-7badc0087470------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*Gjvqzbj5j6EAfz3VbuFK4g.jpeg</url>
            <title>Stories by Dmitry Tikhonov on Medium</title>
            <link>https://medium.com/@0x1000000?source=rss-7badc0087470------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 20:48:41 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@0x1000000/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[5 Common Async Coalescing Patterns]]></title>
            <link>https://itnext.io/5-common-async-coalescing-patterns-db7b1cac1507?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/db7b1cac1507</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[asynchronous-programming]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[multithreading]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Mon, 16 Feb 2026 23:14:00 GMT</pubDate>
            <atom:updated>2026-02-16T23:14:00.608Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lJ2rzoVqQwSIHjfvIsGyrQ.jpeg" /></figure><p>Asynchronous programming is the backbone of responsive applications — both in rich UIs and high-throughput server backends. But with flexibility comes a hidden cost: uncontrolled concurrency.</p><p>A user types into a search box and triggers a request on every keystroke. A backend service issues duplicate fetches because multiple workflows request the same resource at the same time. These are not edge cases — they happen constantly.</p><p>Without control, concurrent async calls lead to redundant work, race conditions, wasted compute, and unpredictable behavior. In UIs this shows up as flickering and stale data. On servers it becomes extra load and hard-to-reproduce bugs. Typical fixes — locks, cancellation tokens, ad-hoc checks — are often incomplete and fragile.</p><p>Coalescing is a more structured approach: merge overlapping async operations and define how they execute and how results are delivered. Instead of letting every request spawn its own task, you shape concurrency explicitly.</p><p><a href="https://devblogs.microsoft.com/dotnet/hybrid-cache-is-now-ga/#cache-stampede-protection">.NET 9 (finally) introduced basic task coalescing in its in-memory cache.</a> Multiple concurrent cache loads collapse into a single execution. This is equivalent to what I call the <strong>Use First</strong> strategy: the first request runs, others await its result.</p><p>But real systems often need different behavior. Sometimes the latest request should win. Sometimes execution should wait until input stabilizes. Sometimes requests must be processed sequentially.</p><p>In this article, I’ll introduce five async coalescing strategies that cover these scenarios and discuss their trade-offs.</p><p><strong>Coalescing Strategies Covered</strong></p><ol><li><strong>Use First</strong> — run once, reuse the result</li><li><strong>Use Last</strong> — cancel previous, keep the newest request</li><li>Use Last with <strong>Debounce</strong> — wait for quiet input, then execute once</li><li><strong>Queue</strong> — process sequentially, return the last result</li><li><strong>Aggregate</strong> — combine multiple requests during a short buffer period</li></ol><p><strong>Resources</strong></p><ol><li><strong>Playground</strong><em>: </em><a href="https://0x1000000.github.io/FlowSync/"><em>runnable demos that simulate concurrent requests and show how each pattern behaves</em>.</a></li><li><strong>Video</strong><em>: visual explanation of concurrency timelines and pattern behavior:</em></li></ol><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FwwSU83Qpjts%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DwwSU83Qpjts&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FwwSU83Qpjts%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/2a2ad062690338d752364adb37f0b7c4/href">https://medium.com/media/2a2ad062690338d752364adb37f0b7c4/href</a></iframe><p>Let’s break them down.</p><h3><strong>1. Use First — Run Once, Reuse Result</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Zg00z6hNOIKRIEBfywFjKw.gif" /></figure><p>In this strategy, when multiple async requests target the same resource concurrently, only the first request is executed. All subsequent overlapping requests are not started — they simply wait for the first request to complete and receive its result. This ensures that no redundant work happens for overlapping calls.</p><p>This is useful when:</p><ul><li>You want to deduplicate overlapping requests</li><li>The result is stable and does not need refreshing</li><li>Re-running the operation is expensive</li><li><strong>Cache lookups</strong>: when fetching a cached value, the first request triggers the load, and all concurrent requests simply await the same result rather than triggering additional loads</li></ul><p>Typical examples include startup initialization, configuration loading, or shared data fetches when multiple UI components initialize simultaneously. With <strong>Use First</strong>, concurrent overlapping requests are <em>never executed</em> — they simply await the result of the first request.</p><p><strong>Use First — Pseudo Code</strong></p><p>To understand how <strong>Use First</strong> works, we can reduce it to a minimal idea. The strategy simply keeps a reference to the currently running task. If a new request arrives while that task is still in progress, it does not start a new operation. Instead, it returns the existing task.</p><pre>// Shared per resource<br>Task&lt;T&gt;? _runningTask;<br><br>public Task&lt;T&gt; Sync(Func&lt;Task&lt;T&gt;&gt; operation)<br>{<br>    // Thread-safety omitted for clarity<br><br>    // If a request is already running, return it.<br>    if (_runningTask != null &amp;&amp; !_runningTask.IsCompleted)<br>        return _runningTask;<br><br>    // Otherwise start a new one.<br>    _runningTask = operation();<br><br>    return _runningTask;<br>}</pre><ul><li>Only the first request actually starts execution.</li><li>Overlapping requests reuse the same Task.</li><li>No cancellation is involved.</li><li>No concurrent execution is possible.</li><li>Once the task completes, the next request may start a new one.</li></ul><h3><strong>2. Use Last</strong> — cancel previous, keep the newest request</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dDd7BU1ww_95EGzJpDxVuQ.gif" /></figure><p>In this strategy, when multiple async requests target the same resource concurrently, only the most recent request is considered the “active” one. Previous overlapping requests are notified to cancel, but they may continue running if cancellation does not happen immediately (or at all). <strong>All callers receive the result of the most recently started request once it completes</strong>, regardless of which request they originally initiated.</p><p>This is useful when:</p><ul><li>You want to always prioritize the latest request</li><li>Earlier requests become irrelevant once a newer one is issued</li><li>Keeping previous operations running is unnecessary or costly</li><li>Dynamic UI updates: such as real-time filtering, search-as-you-type, or slider adjustments, where only the final value matters</li></ul><p>Typical examples include search boxes, live preview filters, or any scenario where user input changes rapidly. With Use Last, <strong>multiple requests may execute concurrently for a short time while cancellation is being processed</strong>. Previous overlapping requests may keep running (which could potentially affect unprotected resources, so be careful), but they do not affect the final result delivered to callers.</p><p><strong>Use Last — Pseudo Code</strong></p><pre>// Shared per resource<br>TaskCompletionSource&lt;T&gt;? _completion;<br>CancellationTokenSource? _cts;<br>Task&lt;T&gt;? _latestTask;<br><br>public Task&lt;T&gt; Sync(Func&lt;CancellationToken, Task&lt;T&gt;&gt; operation)<br>{<br>    // Thread-safety omitted for clarity<br><br>    // Cancel previous execution (if any)<br>    _cts?.Cancel();<br>    _cts = new CancellationTokenSource();<br><br>    // Start new execution<br>    var task = operation(_cts.Token);<br>    _latestTask = task;<br><br>    // Create shared completion source<br>    _completion = new TaskCompletionSource&lt;T&gt;();<br><br>    task.ContinueWith(t =&gt;<br>    {<br>        // Ignore if this is not the latest task<br>        if (_latestTask != t)<br>            return;<br><br>        if (t.IsFaulted)<br>            _completion.TrySetException(t.Exception!);<br>        else<br>            _completion.TrySetResult(t.Result);<br><br>    });<br><br>    return _completion.Task;<br>}</pre><ul><li>A new request cancels the previous one.</li><li>Only the latest task is allowed to complete the shared result.</li><li>Earlier tasks may continue running if they ignore cancellation.</li><li>All callers receive the result of the most recently started request.</li></ul><h3><strong>3. Debounce</strong> — wait for quiet input, then execute once</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3o79SRLVD-iqmC7EfADV9A.gif" /></figure><p>In this strategy, each incoming async request starts a short waiting period (e.g., 1–2 seconds). If no new request arrives during this time, the most recent request at the end of the waiting period is executed. If a new request arrives before the waiting period ends, the timer resets.</p><p>If a request is already running when new input arrives, the running request is notified to cancel, and a new debounce waiting period begins.</p><p>This is useful when:</p><ul><li>You want to avoid executing multiple operations while input is rapidly changing</li><li>Only the final value after a period of inactivity matters</li><li>Operations are expensive and should not run unnecessarily</li><li>User-driven input, such as search boxes, sliders, or filter adjustments</li></ul><p>Typical examples include type-ahead search, live filtering, or form validation. During the waiting period, no execution happens. Once execution starts, a new request will always notify the running operation to cancel and begin a new debounce cycle. If the running operation does not honor cancellation, it may continue executing in parallel, so care is required if it modifies shared or unprotected resources.</p><p><strong>Use Last with Debounce — Pseudo Code</strong></p><p>To understand how <strong>Debounce</strong> works, we combine two ideas:</p><ol><li>Wait for a short period of inactivity before executing.</li><li>If execution is already running and new input arrives, notify the running operation to cancel and start a new debounce cycle.</li></ol><p>The simplified pseudo code looks like this:</p><pre>// Shared per resource<br>CancellationTokenSource? _cts;<br>TaskCompletionSource&lt;T&gt;? _completion;<br>Task&lt;T&gt;? _runningTask;<br>Timer? _timer;<br><br>public Task&lt;T&gt; Sync(Func&lt;CancellationToken, Task&lt;T&gt;&gt; operation)<br>{<br>    // Thread-safety omitted for clarity<br><br>    // Reset debounce timer<br>    _timer?.Dispose();<br><br>    _completion ??= new TaskCompletionSource&lt;T&gt;();<br><br>    _timer = new Timer(_ =&gt;<br>    {<br>        // Cancel currently running task (if any)<br>        _cts?.Cancel();<br>        _cts = new CancellationTokenSource();<br><br>        var task = operation(_cts.Token);<br>        _runningTask = task;<br><br>        task.ContinueWith(t =&gt;<br>        {<br>            if (t.IsFaulted)<br>                _completion.TrySetException(t.Exception!);<br>            else<br>                _completion.TrySetResult(t.Result);<br><br>            _completion = null; // new cycle next time<br><br>        }, TaskContinuationOptions.ExecuteSynchronously);<br><br>    }, null, debounceDelay, Timeout.InfiniteTimeSpan);<br><br>    return _completion.Task;<br>}</pre><ul><li>Each incoming request resets the debounce timer.</li><li>No execution happens until the timer expires.</li><li>When execution starts, a new request cancels the running task.</li><li>Only the final request after inactivity produces a result.</li><li>All callers in the same debounce cycle receive the same result.</li></ul><h3><strong>4. Queue</strong> — process sequentially, return the last result</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UbXugO87rmS1pWt6EwZj9g.gif" /></figure><p>In this strategy, incoming async requests targeting the same resource are added to a queue and executed one at a time, in order of arrival. Each request waits for the previous one to complete before starting. When several requests are queued together, all callers wait, and <strong>only the final request’s result is delivered to everyone</strong>.</p><p>This is useful when:</p><ul><li>You need controlled, sequential execution to avoid race conditions or resource conflicts</li><li>Requests must be processed in order, but only the final outcome matters</li><li>Operations are expensive and should not run concurrently</li><li>Spooler-like scenarios, such as writing to a shared file, updating a database, or processing sequential tasks</li></ul><p>Typical examples include queued background jobs, batched updates, or any scenario where concurrent writes could cause conflicts. With Queue, multiple requests may be waiting while the current one is running, but execution is strictly sequential. Be careful if earlier queued operations have side effects — they will still run, even if their results are not used.</p><p><strong>Queue — Pseudo Code</strong></p><p>The Queue strategy ensures that requests targeting the same resource are executed strictly one at a time, in order of arrival.</p><p>Callers do not receive the result of their individual request. Instead, all callers that arrive while the queue is being processed share a single “batch” completion. When the queue becomes empty, that batch completes and everyone receives the final result from the sequence.</p><p>Below is simplified pseudo code illustrating the idea.</p><pre>Queue&lt;Func&lt;Task&lt;T&gt;&gt;&gt; _queue = new();<br>TaskCompletionSource&lt;T&gt;? _tcs;<br>bool _processing;<br><br>public Task&lt;T&gt; Sync(Func&lt;Task&lt;T&gt;&gt; op)<br>{<br>    lock (_queue)<br>    {<br>        // Add request to the queue<br>        _queue.Enqueue(op);<br><br>        // Start a new batch if needed<br>        _tcs ??= new TaskCompletionSource&lt;T&gt;();<br><br>        // If not already processing, start queue worker<br>        if (!_processing)<br>        {<br>            _processing = true;<br>            _ = ProcessQueue(_tcs); // capture current batch<br>        }<br><br>        // All callers in this batch wait for the same result<br>        return _tcs.Task;<br>    }<br>}<br><br>async Task ProcessQueue(TaskCompletionSource&lt;T&gt; batchTcs)<br>{<br>    T lastResult = default!;<br><br>    try<br>    {<br>        while (true)<br>        {<br>            Func&lt;Task&lt;T&gt;&gt;? op;<br><br>            lock (_queue)<br>            {<br>                // If queue is empty, finish the batch<br>                if (_queue.Count == 0)<br>                {<br>                    _processing = false;<br>                    _tcs = null; // next request creates new batch<br>                    break;<br>                }<br><br>                // Dequeue next request<br>                op = _queue.Dequeue();<br>            }<br><br>            // Execute sequentially<br>            lastResult = await op();<br>        }<br><br>        // Complete batch for ALL callers<br>        batchTcs.TrySetResult(lastResult);<br>    }<br>    catch (Exception ex)<br>    {<br>        // If something fails, fault the entire batch<br>        lock (_queue)<br>        {<br>            _processing = false;<br>            _tcs = null;<br>        }<br><br>        batchTcs.TrySetException(ex);<br>    }<br>}</pre><ul><li>Only one request executes at a time (strict sequential processing).</li><li>Multiple callers may be waiting while the current request runs.</li><li>Earlier queued operations still execute, even if their individual results are not returned.</li><li>All callers that joined the same processing cycle receive the final result of that sequence.</li><li>A new request after the queue drains starts a new batch with a new completion source.</li></ul><h3><strong>5. Aggregate</strong> — combine multiple requests during a short buffer period</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_Rzy0J3cCiEHSBIU3rEnYw.gif" /></figure><p>In this strategy, incoming async requests are collected for a short buffer period (e.g., 1–2 seconds). Instead of executing each request individually, their input values are accumulated using a user-defined aggregation function. When the buffer period ends, a single operation is executed using the aggregated value.</p><p>If new requests arrive while the aggregated operation is running, they are added to a new accumulator. Once the current execution completes, the next aggregated batch is processed. All callers within the same aggregation window receive the result of the combined operation.</p><p>This is useful when:</p><ul><li>Multiple small requests can be merged into a single larger operation</li><li>The underlying work benefits from batching</li><li>Reducing the number of executions is more important than immediate responsiveness</li><li>Accumulated state (e.g., sums, collections, updates) can be safely combined</li></ul><p>Typical examples include batching database writes, grouping telemetry events, combining UI updates, or implementing spooler-like processing where many inputs can be merged before execution. With Aggregate, only one execution happens per buffer window, but care is required if aggregated operations modify shared state. The aggregation function must be deterministic and safe, since multiple requests are combined into a single logical operation.</p><p><strong>Aggregate — Pseudo Code</strong></p><p>Aggregate collects incoming requests during a short buffer window (for example, 1.5 seconds), combines their values using an aggregation function, and then executes a single operation with the combined value.</p><p>If new requests arrive while the operation is running, they are accumulated for the next execution cycle.</p><pre>on request(value):<br><br>    if not running:<br>        add value to accumulator<br>        reset buffer timer<br><br>    else:<br>        add value to nextAccumulator<br><br>when buffer timer expires:<br><br>    running = true<br>    result = execute(accumulator)<br>    complete all callers in this batch with result<br><br>    accumulator = nextAccumulator<br>    nextAccumulator = empty<br><br>    if accumulator not empty:<br>        execute immediately (no new delay)<br>    else:<br>        running = false</pre><ul><li>Requests are grouped during a short buffer window.</li><li>Only one execution happens per buffer cycle.</li><li>While running, new requests form the next batch.</li><li>When the current run finishes, the next batch runs immediately.</li><li>Each caller receives the result of the batch they joined.</li></ul><h3>Summary of Coalescing Strategies</h3><p>The five strategies differ in how they control execution order, cancellation behavior, and result delivery. The table below summarizes their core semantics.</p><pre>| Strategy  | Execution Model                                       | Cancellation Behavior                                      | Concurrency                          | Result Delivery                                     | Typical Use Case                            |<br>| ----------| ----------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------ | --------------------------------------------------- | ------------------------------------------- |<br>| Use First | First request runs; overlapping requests do not start | No cancellation                                            | No concurrent execution              | All callers receive first result                    | Cache loading, initialization               |<br>| Use Last  | Latest request becomes active                         | Previous requests are notified to cancel                   | Possible during cancellation overlap | All callers receive last result                     | Search, dynamic UI updates                  |<br>| Queue     | Requests execute sequentially in order                | No cancellation                                            | No concurrent execution              | All callers receive final result of the sequence    | Spoolers, ordered updates                   |<br>| Debounce  | Execution delayed until inactivity period ends        | Running request is notified to cancel if new input arrives | Possible during cancellation overlap | All callers receive final result after quiet period | Rapid user input, sliders, filters          |<br>| Aggregate | Requests are buffered and combined before execution   | No implicit cancellation between windows                   | One execution per buffer window      | All callers receive aggregated result               | Batching writes, telemetry, grouped updates |</pre><h3>FlowSync — Applying Coalescing as a Strategy</h3><p>The patterns described above are not theoretical. They are implemented in <a href="https://github.com/0x1000000/FlowSync"><strong>FlowSync</strong></a>, a small library that formalizes async coalescing as an explicit strategy.</p><p>Instead of manually wiring TaskCompletionSource, CancellationTokenSource, queues, timers, and locking logic for every use case, FlowSync separates:</p><ul><li><strong>Business logic</strong> (what the operation does)</li><li><strong>Concurrency semantics</strong> (how overlapping calls behave)</li></ul><p>This separation is the key design principle of the library.</p><p>Repository: <a href="https://github.com/0x1000000/FlowSync">https://github.com/0x1000000/FlowSync</a></p><p><strong>Core Idea</strong></p><p>A method is written as a normal async operation, but returns a FlowSyncTask&lt;T&gt;:</p><pre>public async FlowSyncTask&lt;int&gt; FetchAsync(int id)<br>{<br>    var ctx = await FlowSyncTask.GetCancellationContext();<br>    // ctx.CancellationToken covers both:<br>    // 1) explicit external cancellation<br>    // 2) strategy-enforced cancellation due to coalescing/overlap<br>    // ctx.IsCancelledLocally is true only for case (2).<br>    <br>    // Do work here and respect ctx.CancellationToken if needed.<br>    await Task.Delay(Random.Shared.Next(50, 501), ctx.CancellationToken);<br>    return id + 42;<br>}</pre><p>The method itself contains no synchronization logic.<br> It simply respects the cancellation context provided by FlowSync.</p><p>Then, at the call site, you choose the strategy:</p><pre>// Strategy keeps per-group coalescing state across calls, so share one instance.<br>static readonly IFlowSyncStrategy&lt;int&gt; Strategy = new UseLastCoalescingSyncStrategy&lt;int&gt;();<br><br>public async Task&lt;int&gt; CallerAsync(int id)<br>{<br>    // CallerAsync can be invoked concurrently (for example from different threads).<br>    // For the same groupKey, each call awaits strategy resolution and completes when<br>    // the coalesced pipeline finishes (or is canceled); a given invocation may never start its own FetchAsync execution.<br>    return await FetchAsync(id).CoalesceInGroupUsing(Strategy, groupKey: id);<br>}<br></pre><p>Each coalescing pattern is implemented as a strategy:</p><ul><li>UseFirstCoalescingSyncStrategy</li><li>UseLastCoalescingSyncStrategy</li><li>QueueCoalescingSyncStrategy</li><li>DeBounceCoalescingSyncStrategy</li><li>AggCoalescingSyncStrategy</li></ul><p>All strategies follow the same abstraction but differ in semantics:</p><ul><li>Should previous calls be ignored?</li><li>Should they be cancelled?</li><li>Should execution be delayed?</li><li>Should calls be queued?</li><li>Should inputs be aggregated?</li></ul><p>The operation does not change. Only the synchronization policy changes (<strong>Aggregation </strong>is a small exception).</p><p>This makes concurrency behavior explicit and configurable instead of implicit and scattered across code.</p><p>Asynchronous concurrency is not just a technical detail — it shapes how systems behave under real load. Without explicit control, overlapping async calls lead to race conditions, wasted work, and unpredictable results. Coalescing introduces structure: it defines which requests matter, when execution happens, and how results are delivered. Use First, Use Last, Queue, Debounce, and Aggregate are not the only possible strategies, but they represent common and practical patterns that cover many real-world scenarios. Making the chosen behavior explicit makes async code easier to reason about, easier to test, and more reliable.</p><h3>Links</h3><ul><li>FlowSync GitHub Repository: <a href="https://github.com/0x1000000/FlowSync">https://github.com/0x1000000/FlowSync</a></li><li>Interactive Playground (Live Demo): <a href="https://0x1000000.github.io/FlowSync/">https://0x1000000.github.io/FlowSync/</a></li><li>YouTube Video Version: <a href="https://www.youtube.com/watch?v=wwSU83Qpjts">https://www.youtube.com/watch?v=wwSU83Qpjts</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=db7b1cac1507" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/5-common-async-coalescing-patterns-db7b1cac1507">5 Common Async Coalescing Patterns</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Achieving Allocation-Free Polymorphism in C#]]></title>
            <link>https://itnext.io/achieving-allocation-free-polymorphism-in-c-8eb3c99edbce?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/8eb3c99edbce</guid>
            <category><![CDATA[object-oriented]]></category>
            <category><![CDATA[c-sharp-programming]]></category>
            <category><![CDATA[software-performance]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Sat, 16 Mar 2024 23:59:17 GMT</pubDate>
            <atom:updated>2024-07-18T17:15:39.869Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tuA2pqWzANJCUAvSKWIK9g.png" /></figure><p>Polymorphism is a fundamental concept in object-oriented programming and serves as the basis for many commonly used design patterns in software development. However, in runtimes that use garbage collection, such as .Net, Java, and Go, many common design patterns that imply using polymorphism can have some overhead from a performance perspective, as they often entail memory allocations with consequent garbage collection cycles, which in turn can be crucial for high-load applications.</p><p>The initial approach that comes to mind for avoiding memory allocation is to utilize structures located on the stack. However, a critical issue arises: the structure data (when on the stack) does not inherently form an actual object with a link to its type and a list of virtual functions. Consequently, this limitation prevents the direct use of structures in situations that involve polymorphic calls, as they necessitate late binding performed through the virtual function table.</p><p>Nevertheless, C# offers a workaround that enables structures to implement interfaces, allowing them to be used in situations where actual classes would otherwise be necessary. This workaround is known as “boxing”. The concept behind boxing is that whenever a structure is cast to its interface (implicitly or explicitly), .NET creates an object on the heap and copies the structure data into it. This object now possesses a link to its type and, consequently, a link to the virtual function table, enabling polymorphic calls.</p><p>While the formal goal is achieved, the performance consequences are critical. In addition to the fact that memory allocation still occurs, it can now happen every time a structure is cast to its interface. Given that this allocation occurs implicitly, detecting this performance glitch can be challenging. I have even come across recommendations for beginning C# programmers not to use structures, since the likelihood of ruining performance is quite high.</p><p>However, there is a technique that prevents .NET from boxing and can ultimately lead to a significant performance boost. If the sole purpose of boxing is to establish a link to the type, it can be avoided by passing the link through other means, such as using a generic parameter.</p><p>So instead of a function contract like this:</p><pre>void Do(ISomeInterface interfaceImplementation) {<br>    interfaceImplementation.SomeMethod();<br>}</pre><p>the following contract should be used:</p><pre>void Do&lt;TSome&gt;(ref TSome interfaceImplementation) where TSome : ISomeInterface {<br>    interfaceImplementation.SomeMethod();<br>}</pre><p>Now we can pass a structure to the method, and no boxing will occur, as the virtual function table can be obtained from the generic parameter <strong>TSome</strong>.</p><p>To illustrate the concept, let’s examine an example in which the well-known design pattern ‘Visitor’ is implemented using both classes and structures, considering the implications associated with each version.</p><h3>Example</h3><p>I frequently utilize the “Visitor” design pattern to safely switch over an enumeration. I have even <a href="https://github.com/0x1000000/EnumVisitorGenerator">created a source generator that automatically implements this pattern</a>.</p><p>The concept is as follows: there exists an enumeration, along with an interface that includes a corresponding method for each enumeration member:</p><pre>enum Color<br>{<br>    Red,<br>    Green,<br>    Blue<br>}<br><br>interface IColorVisitor&lt;out T, in TArg&gt;<br>{<br>    T CaseRed(TArg arg);<br>    T CaseGreen(TArg arg);<br>    T CaseBlue(TArg arg);<br>}</pre><p>There exists a helper method that receives a value from the enumeration and an interface implementation. This method checks the value and invokes the corresponding interface method:</p><pre>static T Accept&lt;T, TArg&gt;(this Color source, IColorVisitor&lt;T, TArg&gt; visitor, TArg arg)<br>{<br>    switch (source)<br>    {<br>        case Color.Red:<br>            return visitor.CaseRed(arg);<br>        case Color.Green:<br>            return visitor.CaseGreen(arg);<br>        case Color.Blue:<br>            return visitor.CaseBlue(arg);<br>        default:<br>            throw new ArgumentOutOfRangeException(nameof(source), source, null);<br>    }<br>}</pre><p>The advantage of this approach is that the ‘switch’ operator can be isolated from the actual logic, resulting in cleaner and safer code.</p><p>Now let’s create a generic version of the method:</p><pre>static T Accept&lt;T, TVisitor, TArg&gt;(this Color source, ref TVisitor visitor, TArg arg)<br>    where TVisitor : IColorVisitor&lt;T, TArg&gt;<br>{<br>    switch (source)<br>    {<br>        case Color.Red:<br>            return visitor.CaseRed(arg);<br>        case Color.Green:<br>            return visitor.CaseGreen(arg);<br>        case Color.Blue:<br>            return visitor.CaseBlue(arg);<br>        default:<br>            throw new ArgumentOutOfRangeException(nameof(source), source, null);<br>    }<br>}</pre><p>and run the benchmark for each situation:</p><pre>[MemoryDiagnoser]<br>public class Program<br>{<br>    public static void Main()<br>    {<br>        BenchmarkRunner.Run&lt;Program&gt;();<br>    }<br><br>    const int Iterations = 1000;<br><br>    [Benchmark]<br>    public void Class()<br>    {<br>        var visitor = new VisitorClass();<br>        for (int i = 0; i &lt; Iterations; i++)<br>        {<br>            Color.Green.Accept(visitor, true);<br>        }<br>    }<br><br>    [Benchmark]<br>    public void StructBoxing()<br>    {<br>        var visitor = new VisitorStruct();<br>        for (int i = 0; i &lt; Iterations; i++)<br>        {<br>            Color.Green.Accept(visitor, true);<br>        }<br>    }<br><br>    [Benchmark]<br>    public void StructNoBoxing()<br>    {<br>        var visitor = new VisitorStruct();<br>        for (int i = 0; i &lt; Iterations; i++)<br>        {<br>            Color.Green.Accept&lt;string, VisitorStruct, bool&gt;(ref visitor, true);<br>        }<br>    }<br>}<br><br>public class VisitorClass : IColorVisitor&lt;string, bool&gt;<br>{<br>    public string CaseRed(bool eng) =&gt; eng ? &quot;Red&quot; : &quot;Rojo&quot;;<br><br>    public string CaseGreen(bool eng) =&gt; eng ? &quot;Green&quot; : &quot;Verde&quot;;<br><br>    public string CaseBlue(bool eng) =&gt; eng ? &quot;Blue&quot; : &quot;Azul&quot;;<br>}<br><br>public struct VisitorStruct : IColorVisitor&lt;string, bool&gt;<br>{<br>    public string CaseRed(bool eng) =&gt; eng ? &quot;Red&quot; : &quot;Rojo&quot;;<br><br>    public string CaseGreen(bool eng) =&gt; eng ? &quot;Green&quot; : &quot;Verde&quot;;<br><br>    public string CaseBlue(bool eng) =&gt; eng ? &quot;Blue&quot; : &quot;Azul&quot;;<br>}</pre><p>The results are following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nHdWuyhnsHKZ-Vycpt90Qw.png" /></figure><p>Utilizing structures with boxing yields significantly worse results, particularly from a memory allocation perspective. It consumes 1000 times more memory, as allocation occurs during each iteration. Conversely, the version without boxing incurs no allocations and runs much faster than any other version.</p><p><em>Note: The performance boost visible in the “StructNoBoxing” version, compared to the “Class” version, is attributed to the fact that the JIT compiler aggressively inlines method invocations with struct parameters.</em></p><h3>Internals</h3><p>Examining the IL code clarifies the mechanics of polymorphic calls with structures:</p><pre>static T Accept&lt;T, TVisitor, TArg&gt;(this Color source, ref TVisitor visitor, TArg arg)<br>    where TVisitor : IColorVisitor&lt;T, TArg&gt;<br>{<br>    switch (source)<br>    {<br>...<br>        case Color.Green:<br>    // IL_00xx: constrained. !!1/*TVisitor*/<br>    // IL_00xx: callvirt     instance !0/*T*/ class EnumVisitorGenerator.IntegrationTests.IColorVisitor`2&lt;!!0/*T*/, !!2/*TArg*/&gt;::CaseGreen(!1/*TArg*/)<br>            return visitor.CaseGreen(arg);<br>...<br><br>    }<br>}</pre><p><a href="https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-8.0&amp;redirectedfrom=MSDN">The <strong>constrained</strong> prefix instructs the <strong>callvirt</strong> instruction</a> to utilize the virtual function table of the specified type. If the type is a value type, the pointer to the beginning of the structure (located on the stack) serves as the ‘this’ pointer, eliminating the need for boxing.</p><h3>— — — —</h3><p>While the technique described here cannot be universally applied as it functions only when the type is known in advance and the scope is confined to a synchronous function call. Furthermore, the resulting code lacks clarity and requires close attention to avoid performance degradation. Nevertheless, it remains applicable in many situations where performance is of utmost importance.</p><p>Source code: <a href="https://github.com/0x1000000/EnumVisitorGenerator/blob/main/EnumVisitorGenerator.IntegrationTests/Program.cs">https://github.com/0x1000000/EnumVisitorGenerator/blob/main/EnumVisitorGenerator.IntegrationTests/Program.cs</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8eb3c99edbce" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/achieving-allocation-free-polymorphism-in-c-8eb3c99edbce">Achieving Allocation-Free Polymorphism in C#</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Advanced Typescript Techniques: State Tracking as an Example]]></title>
            <link>https://itnext.io/advanced-typescript-techniques-state-tracking-as-an-example-3500cb648ec1?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/3500cb648ec1</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[state-management]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Sun, 30 Apr 2023 21:44:15 GMT</pubDate>
            <atom:updated>2023-05-01T06:30:50.882Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/712/1*G2GZHwsAEa7uRCFUDwiLxQ.png" /></figure><p>Without a doubt, Typescript provides a wide range of possibilities for describing object types. In fact, the range is so extensive that even experienced developers may find it challenging to comprehend what the possibilities are for. For a long time, I didn’t understand why Typescript has such a complex type system until I encountered a practical task where Typescript’s capabilities proved to be extremely useful.</p><p>I am developing <a href="https://github.com/0x1000000/ngSetState">a state management library</a> that create an immutable snapshot of the properties of some class when at least one of its properties has been changed. This snapshot is compared with the previous one, and if the library detects that a property associated with some modifier (essentially a static function) has changed, then that modifier is called with the current snapshot as an argument. The result of this call applies to the properties of the class. Here is an example of how it can look like:</p><pre>class Component {<br>  constructor(<br>     readonly $userId: Observable&lt;number&gt;,<br>     readonly userService: UserService) {<br><br>     initializeImmediateStateTracking&lt;Component&gt;(this);<br>  }<br><br>  firstName: string;<br><br>  lastName: string;<br><br>  readonly greetings = new Subject&lt;string&gt;();<br><br>  @With&lt;Component&gt;(&#39;firstName&#39;, &#39;lastName&#39;)<br>  static greet(state: ComponentState&lt;Component&gt;): StateDiff&lt;Component&gt; {<br>    return {<br>      greetings: `Hi, ${state.firstName} ${state.lastName}`<br>    };<br>  }<br><br>  @WithAsync&lt;Component&gt;(&#39;$userId&#39;)<br>  static async loadUser(getState: AsyncContext&lt;Component&gt;)<br>    : Promise&lt;StateDiff&lt;Component&gt;&gt; {<br><br>     const state: ComponentState&lt;Component&gt; = getState();<br><br>     if(state.$userId) {<br>       const userData = await state.userService.getById(state.$userId);<br><br>       return {<br>          firstName: userData.firstName,<br>          lastName: userData.lastName  <br>       };<br>     }<br>     return null;<br>  }<br>}</pre><p>The most interesting part (from the point of view of the topic) is the types <strong>ComponentState&lt;T&gt;</strong> and <strong>StateDiff&lt;T&gt;</strong> which transform the original class <strong>T</strong> in the following way:</p><p><strong>ComponentState&lt;T&gt;</strong><br>• All methods are filtered out.<br>• All subjects and observables are unwrapped.<br>• All remaining properties are marked as read-only.<br>so that</p><pre>type ComponentState&lt;Component&gt; = {<br>  readonly $userId: number;<br>  readonly userService: UserService;<br>  readonly firstName: string;<br>  readonly lastName: string;<br>  readonly greetings: string;<br>}</pre><p><strong>StateDiff&lt;T&gt;</strong><br>• All methods are filtered out.<br>• All observables are filtered out.<br>• All subjects are unwrapped.<br>• All remaining properties are marked as optional.<br>so that</p><pre>type StateDiff&lt;Component&gt; = {<br>  userService? UserService;<br>  firstName? string;<br>  lastName? string;<br>  greetings? string;<br>}</pre><p><em>Note: Typescript does not perform the transformation it just reflects that the library does</em></p><p>Next, I will show how such type conversions can be performed.</p><p>First of all, I want to share my remark that Typescript actually consists of two languages: the first is a well-known JavaScript extension that adds typing capabilities, the second is a type conversion language with its own rules and constructions that do not affect the JavaScript runtime in any way. In what follows, only this second “language” will be discussed.</p><p>Typescript provides a list of type conversion (or type manipulation) features which are <a href="https://www.typescriptlang.org/docs/handbook/2/types-from-types.html">well described in its documentation</a>. Here I will just briefly overview the most important of them:</p><h4>keyof T</h4><p>This operator generates a union of literal types where each type corresponds to a property key of the type.</p><pre>type T = keyof { p1: string, p2: number, p3: ()-&gt;void } <br>//equals<br>type T = &#39;p1&#39; | &#39;p2&#39;| &#39;p3&#39;</pre><h4>Type Indexing</h4><p>If we take a look at a typical type definition, it can resemble a JSON initialization of a JavaScript object where the value of a property is its type:</p><pre>type User = {<br>  userId: number;<br>  firstName: string;<br>  lastName: string;<br>  dob: Date;<br>}</pre><p>Typescript takes advantage of this similarity and enables you to obtain the type of a property by indexing it as if it were a regular JavaScript object:</p><pre>type T1 = User[&#39;userId&#39;]<br>//equals<br>type T1 = &#39;number&#39;<br><br>type T2 = User[&#39;firstName&#39;]<br>//equals<br>type T2 = &#39;string&#39;<br><br>type T3 = User[&#39;dob&#39;]<br>//equals<br>type T3 = Date<br></pre><p>However, this type indexing has more capabilities than the JavaScript one, allowing you to index multiple items simultaneously and receive a union of types:</p><pre>type T = User[&#39;userId&#39;|&#39;firstName&#39;|&#39;lastName&#39;|&#39;dob&#39;]<br>//equals<br>type T = User[keyof User]<br><br>//equals<br>type T = number|string|Date</pre><h4>Conditional types</h4><p>Typescript’s data manipulation language includes a ternary operator that can be used in the following way:</p><pre>TypeA extends TypeB ? TypeExpression1 : TypeExpression2</pre><p>The <strong>TypeA extends TypeB</strong> operator can be thought of as a boolean expression that verifies whether the following statements are true: <strong>TypeA</strong> is equivalent to <strong>TypeB</strong>, or <strong>TypeB</strong> is assignable to <strong>TypeA</strong>, since <strong>TypeB</strong> is a subset of <strong>TypeA</strong>.</p><p><strong>TypeExpression</strong> can be an exact type or any other type manipulation expression, such as another conditional type.</p><p>Example:</p><pre>type TypeA = {<br>    typeAid: string;<br>}<br><br>type TypeB = {<br>    typeBid: number;<br>}<br><br>function getId&lt;T extends TypeA|TypeB&gt;(obj: T): T extends TypeA <br>    ? T[&#39;typeAid&#39;] <br>    : T extends TypeB <br>        ? T[&#39;typeBid&#39;] <br>        : never {<br><br>     return ((obj as TypeA).typeAid ?? (obj as TypeB).typeBid) as any;<br>}<br><br>const idS: string = getId({typeAid: &#39;id5&#39;});<br>const idN: number = getId({typeBid: 5});</pre><p><em>The function’s resulting type depends on an object that is passed as an argument.</em></p><p><strong>Mapped Types</strong></p><p>The type mapping expression is the most powerful feature of the type manipulation language. It allows you to generate almost any type using a union of types as an input argument. In pseudo language, this expression can be represented as a pure function like this:</p><pre>TOutput = &lt;<strong>mapping expression</strong>&gt;(&lt;<strong>some union of types</strong>&gt;, … other types or generic parameters)</pre><p>or more precisely</p><pre>TOutput = {<br>   &lt;+-readonly&gt; <strong>fk</strong>(x1, ...other types)&lt;+-?&gt;: <strong>ft</strong>(x1, ...other types)<br>   &lt;+-readonly&gt; <strong>fk</strong>(x2, ...other types)&lt;+-?&gt;: <strong>ft</strong>(x2, ...other types)<br>...<br>   &lt;+-readonly&gt; <strong>fk</strong>(xN, ...other types)&lt;+-?&gt;: <strong>ft</strong>(xN, ...other types)<br>}</pre><p>where</p><ul><li><strong>x — </strong>is an item of the union of types</li><li><strong>fk — </strong>is an expression that returns a type property key that should be on the following types<strong>:</strong> <strong>symbol</strong>, <strong>string,</strong> <strong>number</strong> or <strong>never </strong>* (in this case the output type will not contain a property for the item of the union of types)</li><li><strong>ft — </strong>is an expression that returns a type property key</li></ul><p>The type mapping expression has the following syntax in Typescript:</p><pre><strong>{</strong>  <br>  <em>&lt;optional key readonly modifier&gt;</em><br>  <strong>[</strong><em>&lt;type tag&gt;</em> in <em>&lt;union of types&gt;</em> <strong>as</strong> <em>&lt;property key expression&gt;</em><strong>]</strong><br>    <em>&lt;key optionality modifier&gt;</em><strong>:</strong> <em>&lt;property type expression&gt;</em><br><strong>}</strong></pre><p>where</p><ul><li><strong><em>&lt;union of types&gt;</em></strong> is any expression that returns a type union e.g.:</li></ul><pre>&#39;p1&#39;|&#39;p2&#39;|&#39;p3&#39;<br>//or<br>keyof T<br>//or<br>Dog|Cat</pre><ul><li><strong><em>&lt;type tag&gt; </em></strong>is an identifier that represent an item in the union of types (it corresponds to “<strong>x”</strong> in the pseudo language definition)</li><li><strong><em>&lt;property key expression&gt;</em></strong> is an expression that generates a property name from an item of the input union of types represented by the type tag (it corresponds to “<strong>fk”</strong> function in the pseudo language definition). In this expression you can use conditional types and string interpolation (see the examples below). It is optional unless an item of the input union is not string literal type, in this case the expression must return some string literal type.</li><li><strong><em>&lt;property type expression&gt;</em></strong> is an expression that generates a property type from an item of the input union of types represented by the type tag (it corresponds to “<strong>fk” </strong>function in the pseudo language definition). In this expression you can use any Typescript expression that returns a type (e.g. generics, exact types, conditional types etc.)</li><li><strong><em>&lt;key readonly modifier&gt;</em></strong> can be <strong>+readonly </strong>or <strong>-readonly</strong>.<strong> </strong>It ads or removes <strong>readonly </strong>modifier for a property key</li><li><strong><em>&lt;key optionality modifier&gt;</em></strong><em> </em>can be <strong>+? </strong>or <strong>-?</strong> .<strong> </strong>It ads or removes “<strong>?” </strong>modifier for a property key.</li></ul><p><strong>Example #1</strong></p><pre>type T = { [K in &#39;p1&#39;|&#39;p2&#39;|&#39;p3&#39; ]: number }<br><br>//equals<br><br>type T = {<br>    p1: number;<br>    p2: number;<br>    p3: number;<br> }</pre><p>where</p><ul><li><strong><em>&lt;union of types&gt;</em></strong> is ‘p1’|’p2&#39;|’p3&#39;</li><li><strong><em>&lt;type tag&gt; </em></strong>is <strong>K</strong></li><li><strong><em>&lt;property key expression&gt;</em></strong> is omitted since type tag<strong> K</strong> already represents the required string literal type.</li><li><strong><em>&lt;property type expression&gt; </em></strong>is<strong> number</strong></li></ul><p><strong>Example #2</strong></p><pre>type T = { [K in keyof User as `set${Capitalize&lt;K&gt;}` ]: (value: User[K]) =&gt; void }<br><br>//equals<br><br>type T2 = {<br>    setUserId: (value: number) =&gt; void;<br>    setUserFirstName: (value: string) =&gt; void;<br>    setUserLastName: (value: string) =&gt; void;<br>    setUserBob: (value: string) =&gt; void;<br> }</pre><p>where</p><ul><li><strong><em>&lt;union of types&gt;</em></strong> is <strong>keyof User</strong> which is the same as <strong>‘userId’|‘fistName’|‘lastName’|‘dob’</strong></li><li><strong><em>&lt;type tag&gt; </em></strong>is <strong>K</strong></li><li><strong><em>&lt;property key expression&gt;</em></strong> is <strong>`set${Capitalize&lt;K&gt;}`</strong>, which is an example of using <a href="https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html">string interpolation and intrinsic string manipulation functions</a> to generate property keys of the resulting type.</li><li><strong><em>&lt;property type expression&gt; </em></strong>is<strong> (value: User[K]) =&gt; void</strong>, which is an example of type indexing.</li></ul><p><strong>Example #3</strong></p><pre>type WithTypeTag = {<br>    $type: string;<br>}<br><br>type Cat = {<br>    $type: &#39;cat&#39;;<br>}<br><br>type Dog = {<br>    $type: &#39;dog&#39;;<br>}<br><br>type Visitor&lt;T&gt; = { <br>    [K in T as K extends WithTypeTag ? `visit${Capitalize&lt;K[&#39;$type&#39;]&gt;}` : never]<br>    : (value: K) =&gt; void <br>}<br><br>type T = Visitor&lt;Cat|Dog|User&gt;;<br><br>//equals<br><br>type T = {<br>    visitCat: (value: Cat) =&gt; void;<br>    visitDog: (value: Dog) =&gt; void;<br>}</pre><ul><li><strong><em>&lt;union of types&gt;</em></strong> is <strong>Cat|Dog|User </strong>(through the generic parameter). Unlike the previous examples, this union is comprise of regular types, but not string literals.</li><li><strong><em>&lt;type tag&gt; </em></strong>is still <strong>K </strong>which is one of <strong>Cat|Dog|User.</strong></li><li><strong><em>&lt;property key expression&gt;</em></strong> is <strong>K extends WithTypeTag ? `visit${Capitalize&lt;K[‘$type’]&gt;}` : never</strong>. It checks if a type has the type tag property. If the property is found then its type is used to generate a visitor method name, otherwise nothing will be emitted into the resulting type (the keyword is <strong>never</strong>).</li><li><strong><em>&lt;property type expression&gt; </em></strong>is<strong> (value: K) =&gt; void</strong>. Since the union is comprise of regular types then it is possible to use the tag as it is (the type indexing is not required here).</li></ul><h3>Solutions</h3><p>Now that we have a basic understanding of type manipulation in Typescript, we can use this knowledge to solve the tasks that were introduced at the beginning of this post:</p><p><strong>ComponentState&lt;T&gt;</strong><br>• All methods are filtered out:</p><pre>type WithoutFunctions&lt;T&gt; = <br>    {[K in keyof T as T[K] extends Function ? never : K]: T[K]}</pre><p>• All subjects and observables are unwrapped:</p><pre>type Unwrap&lt;T&gt; = {<br>    [K in keyof T]: T[K] extends Observable&lt;infer TO&gt; <br>        ? TO <br>        : (T[K] extends Subject&lt;infer TS&gt; ? TS : T[K])<br>};</pre><p>• All remaining properties are marked as read-only:</p><pre>type Readonly&lt;T&gt; = {<br>    +readonly [K in keyof T]: T[K]<br>};</pre><p>All together:</p><pre>type ComponentState&lt;T&gt; = {<br>    +readonly [K in keyof T as T[K] extends Function ? never : K]<br>        : T[K] extends Observable&lt;infer TO&gt;<br>            ? TO<br>            : T[K] extends Subject&lt;infer TS&gt; ? TS : T[K]<br>};<br><br>type T = ComponentState&lt;Component&gt;;<br><br>//equals<br><br>type T = {<br>    readonly $userId: number;<br>    readonly userService: UserService;<br>    readonly firstName: string;<br>    readonly lastName: string;<br>    readonly greetings: string;<br>}</pre><p>Similar for <strong>StateDiff&lt;T&gt;</strong>:</p><pre>type StateDiff&lt;T&gt; = {<br>    -readonly [<br>        K in keyof T as <br>        T[K] extends Function ? never <br>          : T[K] extends Observable&lt;any&gt; ? never: K <br>     ]+?: T[K] extends Subject&lt;infer TS&gt; ? TS : T[K]<br>};<br><br>type T = StateDiff&lt;Component&gt;;<br><br>//equals<br><br>type T = {<br>    userService?: UserService;<br>    firstName?: string;<br>    lastName?: string;<br>    greetings?: string;<br>}</pre><p>—</p><p>While Typescript’s type manipulation language can be challenging to understand, it can be very useful in certain situations. For example, if you’re creating a library that other developers will use and may not be familiar with your codebase, TypeScript can help ensure that your code is more robust and less error-prone. It’s important to note that the type manipulation language does not affect JavaScript output and is only used during the compilation process.</p><p>Links:</p><p><a href="https://github.com/0x1000000/ngSetState"><strong>ng-set-state</strong></a> — <a href="https://github.com/0x1000000/ngSetState">is the state management library</a> described in this post</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3500cb648ec1" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/advanced-typescript-techniques-state-tracking-as-an-example-3500cb648ec1">Advanced Typescript Techniques: State Tracking as an Example</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Filtering by Dynamic Attributes]]></title>
            <link>https://itnext.io/filtering-by-dynamic-attributes-90ada3504361?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/90ada3504361</guid>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[sql]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Fri, 27 May 2022 20:05:10 GMT</pubDate>
            <atom:updated>2025-03-07T00:08:23.491Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J3uZ84gvOSaAu4w_ILclEA.png" /></figure><p>In development, there is a very common situation when it becomes necessary to work with dynamic attributes for some entities, even more — the entities themselves can be fully dynamic. I think the most famous example of such application is JIRA where ticket attributes can be added or removed by administrators and then everybody will be able to work with them (review or modify their values for tickets). At the same time, JIRA provides ample opportunities for filtering and sorting tickets using the dynamic attributes which suggests that work with the dynamic attributes is deeply integrated into JIRA data storage, otherwise it would hardly be possible to achieve good performance when dealing with a large number of objects. For example, if there are thousands (millions) of stored objects (e. g. JIRA tickets) and if the filtering were not implemented in the data storage itself, then it would be necessary to read each of the objects into the application memory to check if it matches the filtering and sorting conditions. Obviously, it does not look very efficient.<br>I encountered a similar problem in several projects that I worked on, and using that experience I want to offer a solution that is quite effective, in my opinion.<br><em>Note. In the following, we will focus only on SQL databases. Most likely, many will agree with the statement that SQL databases nowadays are still the most popular way to store application data.</em></p><h3>Table Structure</h3><p>Before filtering data, you must first figure out how to properly organize data in SQL tables. In the simplest scenario table structure for dynamic attributes might look as follows:</p><ul><li><strong>Product</strong> — List of objects which are going to be extended with dynamic attributes</li><li><strong>Attribute</strong> — list of dynamic attributes (name and type)</li><li><strong>ProductAttribute</strong> — dynamic attribute values for the products</li></ul><p>Let’s look at an example where we have a list of mobile phone models and we want to dynamically add some additional attributes, such as ‘vendor’, ‘internal memory (Gb)’, ‘cellular protocols’, ‘release date’ etc.</p><p>In this case, the data might look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Zov89k54-remvbmrIXEwbw.png" /></figure><p>There is one point in this simple structure that can cause certain problems — note that the type of the <strong>Value</strong> column is a string. At first glance, it seems logical since the attribute type can be different, but any of the types can always be represented as a string. However, in terms of filtering and sorting, this is not the best choice, because in general, string comparison does not correspond to encoded value comparison. So for example, when comparing strings <em>‘2.11’</em> and <em>‘11.2’</em> and comparing numbers 2.11 and 11.2, the exact opposite result will be obtained — <em>‘2.11’</em> is “greater” than <em>‘11.2’</em> but 2.11 is less than 11.2</p><p>Another problem with using strings is that the same data can be encoded differently. I think that many developers have met with problems caused by different date formats: 5/29/2022, 2022–05–22, 05.29.2022 — the same date, but different strings.</p><p>Often, attribute values can be more complex structures, such as lists, and if they are encoded as a single string, such values become almost unmanageable at the database level.</p><p>With the above in mind, consider the new table structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*32dfW2XYJzwvtz0QkgZgZw.png" /></figure><p>Now the value table (<strong>ProductAttribute</strong>) has one column for each attribute type (reference, number, date). List values are moved into a separate table <strong>ProductAttributeItem</strong>.</p><p>Using the structure, we can try to select some products that meet certain criteria.</p><h3>SQL Filtering</h3><p>Let’s consider a “complex filter”, for example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FbrV6MGrsIkQHK5RSB3ZOw.png" /></figure><p>In SQL it can be expressed as the :</p><pre><strong>(</strong><br>  <strong>[1]</strong><em>/*Vendor*/</em> = <strong>1</strong><em>/*Apple*/</em> <br>  <strong>AND</strong><br>  <strong>[2]</strong><em>/*Internal Memory*/ </em>&gt;= <strong>64</strong><br>  <strong>AND</strong> <br>  <strong>[2]</strong><em>/*Internal Memory*/</em> &lt;= <strong>256</strong><br><strong>)<br>OR<br>([1]</strong><em>/*Vendor*/</em> = <strong>2</strong><em>/*Samsung*/</em><strong>)</strong></pre><p>The idea is to inject the expression into some SQL query so that the database server does the filtering on its own. In order to do this it needs:</p><ol><li>Analyze what attributes are used in the filter</li><li>Join a value table (<strong>ProductAttribute</strong>) as many times as many unique attributes are present in the filter</li></ol><p>The filter contains two attributes:</p><ul><li><strong>[1] Vendor</strong> — reference to the enumeration</li><li><strong>[2] Internal Memory</strong> — number</li></ul><p>So, the final query should contain a sub query where <strong>ProductAttribute</strong> is joined two times with proper column aliases:</p><pre><strong>SELECT</strong><br>    [ATTRIBUTES].ProductId<br><strong>FROM</strong><br><strong>(</strong><br>    <strong>SELECT</strong><br>        [P].ProductId,<br>        [AT_1].ValueItem <strong>[1]</strong>,<br>        [AT_2].ValueInt <strong>[2]</strong><br>    <strong>FROM</strong> Product<br>        [P]<br>    <strong>LEFT JOIN</strong> ProductAttribute<br>        [AT_1] ON<br>        [AT_1].AttributeId = <strong>1</strong>/*Vendor*/<br>        AND<br>        [AT_1].ProductId = [P].ProductId<br>    <strong>LEFT JOIN</strong> ProductAttribute<br>        [AT_2] ON<br>        [AT_2].AttributeId = <strong>2</strong>/*Internal Memory*/<br>        AND<br>        [AT_2].ProductId = [P].ProductId<br><strong>)</strong> [ATTRIBUTES]<br><strong>WHERE<br>(</strong><br>  <strong>[1]</strong><em>/*Vendor*/</em> = <strong>1</strong><em>/*Apple*/</em> <br>  <strong>AND</strong><br>  <strong>[2]</strong><em>/*Internal Memory*/ </em>&gt;= <strong>64</strong><br>  <strong>AND</strong> <br>  <strong>[2]</strong><em>/*Internal Memory*/</em> &lt;= <strong>256</strong><br><strong>)<br>OR<br>([1]</strong><em>/*Vendor*/</em> = <strong>2</strong><em>/*Samsung*/</em><strong>)</strong></pre><p>As we can see, the original filter expression (like any other with the same attributes) can be injected into the query and the filtering will be performed directly in the SQL database. In addition to the fact that this filtering will be very efficient (we will add indexes, right?), we also get the ability to select a range in a sorted data set (pagination with FETCH OFFSET), which would require all the data to be in the application’s memory if filtering was done at the application level.</p><h3>Building dynamic SQL</h3><p>Theoretically, this looks good, but it is not clear how to use this approach in a real application, since the following tasks must be solved first:</p><ol><li>Converting filtering criteria into a SQL boolean expression</li><li>Preparing a proper base selection query with all required joins</li></ol><p>Hardly your ORM is flexible enough to perform these tricks and the first idea that comes to mind is to build dynamic SQL queries as text, which is possible of course but I would recommend using some sql builders that allow working with SQL syntax trees — that would be much safer and flexible solution.</p><p>Further, as an example, I will use <a href="https://github.com/0x1000000/SqExpress">SqExpress </a>library for the .Net platform. Of course, you can use other similar libraries — the principles will remain the same.</p><p>So let’s start by building a boolean expression:</p><p><em>Note: here it is hard-coded but nothing prevents to create it dynamically from some filter model.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/63c5d8f52600df10b7b06be7e5f80e0a/href">https://medium.com/media/63c5d8f52600df10b7b06be7e5f80e0a/href</a></iframe><p>Small check that it is what we want:</p><pre><strong>Console</strong>.WriteLine(<strong>TSqlExporter</strong>.Default.ToSql(filter));</pre><pre>//[1]=1 AND [2]&gt;=64 AND [2]&lt;=256 OR [1]=2</pre><p>Using syntax tree traversal we can find all unique attributes ids in the expression:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3bddbe02af9a1506993d650b2846c993/href">https://medium.com/media/3bddbe02af9a1506993d650b2846c993/href</a></iframe><p>When we know all the attribute ids we can read their types:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ab984d1fc7f56aadd8876884e2a46146/href">https://medium.com/media/ab984d1fc7f56aadd8876884e2a46146/href</a></iframe><p>Now using the information about attributes in the filter expression we can build a sub-query where <strong>ProductAttribute</strong> table will be joined once per an unique attribute:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/02504bceb0d5418347ff02b09b795fff/href">https://medium.com/media/02504bceb0d5418347ff02b09b795fff/href</a></iframe><p>Combining all together:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/277b77a832a70d250cb237af8ac6a1ef/href">https://medium.com/media/277b77a832a70d250cb237af8ac6a1ef/href</a></iframe><p>This works fine with simple attributes, but if an attribute is “Set” (value is a set of items), then more effort will be required. For example, we want to filter by cellular protocols:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7f990a3667e754ee0933b63d8018728/href">https://medium.com/media/d7f990a3667e754ee0933b63d8018728/href</a></iframe><p>To be executed by the database server, this filter query must be modified as follows<strong>: IN</strong> operator should be replaced with <strong>EXISTS </strong>sub-query, so that <strong>ProductAttributeItem</strong> table is used. It can be done by modification the filter syntax tree:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d5afdbbba24f79cfa5bded147addb28e/href">https://medium.com/media/d5afdbbba24f79cfa5bded147addb28e/href</a></iframe><pre><strong>EXISTS</strong><br><strong>(</strong><br>  <strong>SELECT</strong> 1 <br>  <strong>FROM</strong> [dbo].[ProductAttributeItem] <br>    [A0] <br>  <strong>WHERE</strong> <br>     [A0].[AttributeId]=3 <br><strong>     AND</strong> <br>     [A0].[ProductId]=[A1].[ProductId] <br>     <strong>AND</strong> <br>     [A0].[AttributeItemId] <strong>IN(</strong>3,5<strong>)</strong><br><strong>)</strong></pre><p>After the modification the filter can be used in the query:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ac76889c06ea792b5bbeaf936a779fce/href">https://medium.com/media/ac76889c06ea792b5bbeaf936a779fce/href</a></iframe><p>Using the techniques and approaches described above, you can not only create applications with dynamically expanding entities, but also provide a rich functionality for filtering these entities according to various criteria.</p><p>Links:</p><ul><li><a href="https://github.com/0x1000000/SqGoods">SqGoods </a>— it is a demo web application that demonstrates dynamic filtering of dynamic entities;</li><li><a href="https://github.com/0x1000000/DynAttDemo">Source code code for this article</a></li><li><a href="https://github.com/0x1000000/SqExpress">SqExpress </a>— sql query builder used in the article examples. (<a href="https://www.youtube.com/watch?v=Zd-fCb8NimA">Video Tutorial on Youtube</a>)</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=90ada3504361" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/filtering-by-dynamic-attributes-90ada3504361">Filtering by Dynamic Attributes</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Popup Controls in Angular]]></title>
            <link>https://itnext.io/creating-popup-controls-in-angular-bacb5a411caa?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/bacb5a411caa</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[angular]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Tue, 27 Apr 2021 14:25:38 GMT</pubDate>
            <atom:updated>2021-04-28T06:37:11.815Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1020/1*7mMqiCWphrXlH_JU5C_2-g.png" /></figure><p>There are a lot of control types that can be considered as popup controls, e.g. Select, Date-Time picker, Modal dialog etc. All these controls have parts that break out of the layout flow and overlap other UI elements. There are well-known methods for achieving the overlap behavior in HTML, but when developing your own component library in Angular, using these methods can be problematic. Next, we’ll take a look at potential problems with pop-up controls and some tricks to avoid them.</p><h4>Overlays in HTML</h4><p>The most simple and efficient way to create a local-pop is using relative position for a host element and absolute position for a popup:</p><pre>&lt;div id=&quot;host&quot;&gt;<br>  &lt;div id=&quot;control&quot;&gt;<br>    Host<br>    &lt;div id=&quot;popup&quot;&gt;<br>      Popup<br>    &lt;/div&gt;<br>  &lt;/div&gt;<br>&lt;/div&gt;<br>&lt;style&gt;<br>  #host{<br>    width: 90px;<br>    height: 50px;<br>  }</pre><pre>  #control{<br>    position: relative;<br>  }</pre><pre>  #popup{<br>    position: absolute;<br>    top: 30px;<br>    left: 10px;<br>  }<br>&lt;/style&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/417/1*mbCo81On0k5tF7qCuYTl6Q.png" /></figure><p>It works fine if the host element does not hide overflow, otherwise the popup might be clipped, and z-index will not help:</p><pre>#host{<br>  width: 90px;<br>  height: 50px;<br>  overflow: hidden;<br>}</pre><pre>#control{<br>  position: relative;    <br>  z-index: 10000; /*It does not help*/<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/330/1*5cXIDYDkA4JmodOLUBwGcw.png" /></figure><p>Library controls can be placed in any host, so the solution described above cannot be treated as universal.</p><p>Another solution is using <strong>fixed</strong> position for a popup:</p><pre>&lt;div id=&quot;host&quot;&gt;<br>  &lt;div id=&quot;control&quot;&gt;<br>    Control<br>      &lt;div id=&quot;popup&quot;&gt;<br>        Popup<br>      &lt;/div&gt;<br>  &lt;/div&gt;  <br>&lt;/div&gt;<br>&lt;style&gt;<br>  #host{<br>    width: 90px;<br>    height: 50px;<br>    overflow: hidden;<br>  }</pre><pre>  #popup{<br>    position: fixed;<br>    top: 50px;<br>    left: 50px;<br>  }<br>&lt;/style&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/1*xFKc5J7_iPP9SaJlHiqIFg.png" /></figure><p>The disadvantage of this method is that the popup and control positions need to be synchronized via JavaScript, but the main problem is that the control host can initiate <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context">a new stacking context</a> and, as a result, the popup can be overlapped by other elements and z-index again will not help:</p><pre>&lt;div id=&quot;host&quot;&gt;<br>  &lt;div id=&quot;control&quot;&gt;<br>    Control<br>      &lt;div id=&quot;popup&quot;&gt;<br>        Popup<br>      &lt;/div&gt;<br>  &lt;/div&gt;  <br>&lt;/div&gt;<br>&lt;div id=&quot;overlap&quot;&gt;<br>  Overlap<br>&lt;/div&gt;<br>&lt;style&gt;<br>  #host{<br>    width: 90px;<br>    height: 50px;<br>    overflow: hidden;</pre><pre>    /*New stacking context*/<br>    position: relative;<br>    z-index: 0;<br>  }</pre><pre>  #popup{<br>    position: fixed;<br>    top: 50px;<br>    left: 35px;<br>    z-index: 1000;/*It does not help*/<br>  }</pre><pre>  #overlap{<br>    transform: translate(80px, -50px);<br>  }<br>&lt;/style&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/1*4ZvRtAVIhMBiSQA6QzFxEg.png" /></figure><p>The solution here is to render the popup in the root stacking context:</p><pre>&lt;div id=&quot;host&quot;&gt;<br>  &lt;div id=&quot;control&quot;&gt;<br>    Control<br>  &lt;/div&gt;  <br>&lt;/div&gt;<br>&lt;div id=&quot;overlap&quot;&gt;<br>  Overlap<br>&lt;/div&gt;<br>&lt;div id=&quot;popup&quot;&gt;<br>  Popup<br>&lt;/div&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/469/1*ZXSJl7dKkSxFRp4K0fo09g.png" /></figure><p>This trick works, but what should the hapless creators of Angular controls do? These controls can be placed anywhere and how can their popups be moved after an application root? Further, I will show you how to do this.</p><h4><strong>Implementation in Angular</strong></h4><p>The first goal is rendering a popup part anywhere else except for the control itself.</p><p>For example we are developing a drop-down control, and we want the “down” part to be rendered after the application root component:</p><pre>&lt;div class=&quot;l-box&quot;&gt;<br>  &lt;ng-content select=&quot;lib-drop-down-label&quot;&gt;<br>  &lt;/ng-content&gt;<br>&lt;/div&gt;<br>&lt;div class=&quot;l-popup&quot;&gt;<br>  &lt;ng-content select=&quot;lib-drop-down-content&quot;&gt;<br>  &lt;/ng-content&gt;<br>&lt;/div&gt;</pre><p>Using <a href="https://stackblitz.com/edit/angular-popup-modals?file=src/app/lib/directives/popup-rect.directive.ts">an angular structural directive</a> we can catch the popup part as a template and store it in some service:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c50dfe2f4a65768fd03776c029a1cbba/href">https://medium.com/media/c50dfe2f4a65768fd03776c029a1cbba/href</a></iframe><p><a href="https://stackblitz.com/edit/angular-popup-modals?file=src/app/lib/services/popup.service.ts">The Service</a>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6becc429c0e1d154777b75306284dce5/href">https://medium.com/media/6becc429c0e1d154777b75306284dce5/href</a></iframe><p>This is how the detective is used:</p><pre>...<br>&lt;div<br>  *libPopupRect=&quot;isOpen;top:rect.top;left:rect.left;width:rect.width;&quot;<br>    class=&quot;l-popup&quot;&gt;</pre><pre>&lt;ng-content select=&quot;lib-drop-down-content&quot;&gt;<br>  &lt;/ng-content&gt;<br>&lt;/div&gt;</pre><p>Now we need <a href="https://stackblitz.com/edit/angular-popup-modals?file=src/app/lib/components/popup-host/popup-host.component.html">a host component which will render the stored templates</a>:</p><pre>&lt;ng-container *ngFor=&quot;let p of popups&quot;&gt;<br>  &lt;div <br>    class=&quot;l-popup&quot;<br>    [style.top.px]=&quot;p.rect.top&quot; <br>    [style.left.px]=&quot;p.rect.left&quot; <br>    [style.bottom.px]=&quot;p.rect.bottom&quot; <br>    [style.right.px]=&quot;p.rect.right&quot; <br>    [style.width.px]=&quot;p.rect.width&quot; <br>    [style.height.px]=&quot;p.rect.height&quot;<br>    [style.z-index]=&quot;p.rect.zIndex&quot;<br>  &gt;<br>    &lt;ng-container [ngTemplateOutlet]=&quot;p.tr&quot;&gt;&lt;/ng-container&gt;<br>  &lt;/div&gt;<br>&lt;/ng-container&gt;<br>&lt;style&gt;<br>  .l-popup {<br>    position: fixed;<br>    pointer-events: initial;<br>  }  <br>&lt;/style&gt;</pre><p><a href="https://stackblitz.com/edit/angular-popup-modals?file=src/app/lib/components/popup-host/popup-host.component.ts">The component class</a>:</p><pre><a href="http://twitter.com/Component">@Component</a>(...)<br>export class PopupHostComponent {</pre><pre>  popups: PopupData[];<br>    <br>  constructor(private readonly _cd: ChangeDetectorRef) { }</pre><pre>  update(popups: PopupData[]) {<br>    this.popups = popups;<br>    this._cd.detectChanges();<br>  }<br>}</pre><p>Now, using the service, we can dynamically create the host component after the application root:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc3201cad864661f23976286b2776ea8/href">https://medium.com/media/cc3201cad864661f23976286b2776ea8/href</a></iframe><p>In DOM the opened drop-down will look as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/548/1*t-o9hjIIluffHtaJs9bV2w.png" /></figure><h4>Positioning of popups</h4><p>The popups use the <strong>fixed</strong> position and that means that they should be explicitly positioned relative to an anchor:</p><p>For <a href="https://stackblitz.com/edit/angular-popup-modals?file=src/app/lib/components/drop-down/drop-down.component.ts">the drop down</a> we can use the component element ref as an anchor and position the popup when it appears:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/94e93934999654fc358068cab247f1e5/href">https://medium.com/media/94e93934999654fc358068cab247f1e5/href</a></iframe><p>The problem here is that we can not keep the drop-down always opened since any change in the host DOM layout (resizing, scrolling etc.) might lead to incorrect position. The simplest solution of the problem is closing the drop-down popup on any external activity:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/14f99cf02b0b157f2ba040739983c315/href">https://medium.com/media/14f99cf02b0b157f2ba040739983c315/href</a></iframe><p>Other popup controls can also be developed in the same manner. For example <a href="https://stackblitz.com/edit/angular-popup-modals?file=src/app/lib/components/modal-dialog/modal-dialog.component.html"><strong>Modal Dialog</strong></a>.</p><p>—</p><p>The technique described above might look a bit over-complicated but it is a good solution to be 99% sure that your popups will not be overlapped by anything else.</p><p>Link to the example on <a href="https://stackblitz.com/edit/angular-popup-modals">stackblitz</a>: <a href="https://stackblitz.com/edit/angular-popup-modals">https://stackblitz.com/edit/angular-popup-modals</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bacb5a411caa" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/creating-popup-controls-in-angular-bacb5a411caa">Creating Popup Controls in Angular</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular Components State Tracking with ng-set-state]]></title>
            <link>https://itnext.io/angular-components-state-tracking-with-ng-set-state-e2b988540407?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/e2b988540407</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[front-end-development]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Sun, 18 Apr 2021 18:44:51 GMT</pubDate>
            <atom:updated>2021-04-18T18:44:51.531Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*4eM1VL4T9aTxBTCgARmxWQ.png" /></figure><p>In <a href="https://itnext.io/angular-components-with-extracted-immutable-state-86ae1a4c9237?sk=3d9422a57d8ac49a4b1c8de39d6fc0b3">the previous article</a>(“<a href="https://medium.com/p/86ae1a4c9237?source=post_stats_page-------------------------------------">Angular Components with Extracted Immutable State</a>”), I explained why changing component fields without any restrictions is not always good, and also presented a library that allows you to streamline a component state changes.</p><p>Since then, I’ve slightly modified its concept and made it easier to use. This time I’ll focus on a simple (at first glance) example of how it can be used in scenarios where rxJs usually would be needed.</p><h3>Concept</h3><p>There is an immutable object that represents all field values of some component:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/491/1*MrFtcwYTjtbg6nPsbJTMHA.png" /></figure><p>Each time when some field value (or several field values) of the component is changed, then a new immutable object will be created. It will contain all the old unchanged values and the new ones:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/569/1*O88QKy4CYoTeizZnaZx8ig.png" /></figure><p>By comparing these two objects, it can be determined what exact fields values have changed and if there are logical dependencies on these fields then the corresponding value evaluation should be performed. After the evaluation is done then a 3-rd object will be created and this 3-rd object will contain the original values and the newly evaluated ones.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/533/1*T5dQ9NnP9U55JMCN1o8ZIg.png" /></figure><p>Now we have the new object which also can be compared with the previous one and next dependencies can be evaluated if it is required. This scenario can be repeated many times until we have a fully consistent object. After that angular will render its data. Profit!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/650/1*TsHVxdLmgbgSiWgXDyHMxw.png" /></figure><h3>Simple Greeting Form</h3><p>Let’s create a simple greeting form <em>(s</em><a href="https://stackblitz.com/edit/set-state-greet?file=src/app/simple-greeting-form/simple-greeting-form.component.ts"><em>ource code on stackblitz</em></a><em>)</em>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/78cddd5eb53e99b4b550c4f12e93749d/href">https://medium.com/media/78cddd5eb53e99b4b550c4f12e93749d/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/32b25b487b9a6886f058addd145cb019/href">https://medium.com/media/32b25b487b9a6886f058addd145cb019/href</a></iframe><p>Obviously, the <strong>greeting</strong> field depends on the <strong>userName</strong> field and there are several ways to express the dependency:</p><ol><li>Converting <strong>greeting </strong>to a property with a getter, but in this case its value will be calculated on each change detection.</li><li>Converting <strong>userName</strong> to a property with a setter which will update the<strong> greeting </strong>filed value.</li><li>Creating an event handler on “(ngModelChange)” but it will make the markup more complex;</li></ol><p>They will work, but if some other field depends on <strong>greeting</strong> (for example, “greetings counter”) or “greeting” depends on more than one field (e.g.<em> greeting=f(userName, template)</em> ), then none of these methods will help, so another approach is proposed:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ce1c2c86f62c5123c18140320851495/href">https://medium.com/media/3ce1c2c86f62c5123c18140320851495/href</a></iframe><p>First, the component should be decorated with <strong>@StateTracking</strong> decorator, or alternatively <strong>initializeStateTracking</strong> function should be called in the constructor (custom component decorators do not properly works in some old Angular versions):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eeee151ea6a599578eb6b631bb50a105/href">https://medium.com/media/eeee151ea6a599578eb6b631bb50a105/href</a></iframe><p><strong>@StateTracking</strong> decorator (or <strong>initializeStateTracking</strong> function) finds all the component fields which other fields might depend on and replaces them with properties with getters and setters, so that the library can keep track changes.</p><p>Next, some transition function should be defined e.g.:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c260c16fd51ae69d1b96ce44a1521c09/href">https://medium.com/media/c260c16fd51ae69d1b96ce44a1521c09/href</a></iframe><p>Each transition function receives an object that represents a current component state and should return an object which will contain only updated fields. It will be merged into a copy of the current state object. Then the new updated copy will become a new component state.</p><p>Optionally, you can add a second argument which will receive a previous state object.</p><p>If you define a third parameter, it will receive a “difference” object between the current and previous states:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d66e6cfeefa79cce793f127e1735b966/href">https://medium.com/media/d66e6cfeefa79cce793f127e1735b966/href</a></iframe><p><strong>ComponentState</strong> and <strong>ComponentStateDiff</strong> are typescript mapped types which filter out methods and event emitters. Also <strong>ComponentState</strong> marks all fields as <strong>readonly</strong> (state is immutable) and <strong>ComponentStateDiff</strong> marks all fields as optional, since transition function can return any subset of the original state.</p><p>For simplicity let’s define the type aliases:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b3c03b6a2d77eeeef466317a685276f0/href">https://medium.com/media/b3c03b6a2d77eeeef466317a685276f0/href</a></iframe><p>Decorator <strong>@With</strong> receives a list of field names whose value changes will trigger the decorated static (!) method. Typescript will check that the class has the declared fields and that the method is static (transitions should “pure”)</p><h3>Tracking log</h3><p>Now the form displays a corresponding greeting when user types a name. Let’s see how the component state changes:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f108e2f1743c969b2145175eb80f630b/href">https://medium.com/media/f108e2f1743c969b2145175eb80f630b/href</a></iframe><p><strong>onStateApplied</strong> is a hook function which is called each time when the component state becomes consistent — that mans that all transition functions have been called and no more changes detected:</p><pre>Transition:<br>{} =&gt;<br>{&quot;userName&quot;:&quot;B&quot;,&quot;greeting&quot;:&quot;Hello, B!&quot;}</pre><pre>Transition:<br>{&quot;userName&quot;:&quot;B&quot;,&quot;greeting&quot;:&quot;Hello, B!&quot;} =&gt;<br>{&quot;userName&quot;:&quot;Bo&quot;,&quot;greeting&quot;:&quot;Hello, Bo!&quot;}</pre><pre>Transition:<br>{&quot;userName&quot;:&quot;Bo&quot;,&quot;greeting&quot;:&quot;Hello, Bo!&quot;} =&gt;<br>{&quot;userName&quot;:&quot;Bob&quot;,&quot;greeting&quot;:&quot;Hello, Bob!&quot;}</pre><p>As we can see, the component goes to a new state every time user types a next character and the greeting field is updated immediately. If it needs to prevent the greeting from updating on every name change then it can be easily accomplished by adding <strong>Debounce</strong> extension to the <strong>@With</strong> decorator:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0bbcad1001397f048a7abfe8a23704f/href">https://medium.com/media/f0bbcad1001397f048a7abfe8a23704f/href</a></iframe><p>Now the library waits 3 second after the last name change and only then executes the transition:</p><pre>Transition:<br>{} =&gt;<br>{&quot;userName&quot;:&quot;B&quot;}</pre><pre>Transition:<br>{&quot;userName&quot;:&quot;B&quot;} =&gt;<br>{&quot;userName&quot;:&quot;Bo&quot;}</pre><pre>Transition:<br>{&quot;userName&quot;:&quot;Bo&quot;} =&gt;<br>{&quot;userName&quot;:&quot;Bob&quot;}</pre><pre>Transition:<br>{&quot;userName&quot;:&quot;Bob&quot;} =&gt;<br>{&quot;userName&quot;:&quot;Bob&quot;,&quot;greeting&quot;:&quot;Hello, Bob!&quot;}</pre><p>Let’s add an indication that the form is waiting:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4104104c711baf86d3604de8649de06f/href">https://medium.com/media/4104104c711baf86d3604de8649de06f/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a53d0d3e708c8f5cf0d9bebaec4fac34/href">https://medium.com/media/a53d0d3e708c8f5cf0d9bebaec4fac34/href</a></iframe><p>It seems working but an issue appears — if a user started typing and then decided to return the original name during the given 3 seconds, then from the “greet” transition perspective nothing has changed and the function will never called and the form will keep “thinking” forever unit you type a different name. It can be solved by adding <strong>@Emitter()</strong> decorator for <strong>userName</strong> field:</p><pre>@Emitter()<br>userName: string;</pre><p>which says to the library, that any assignment of any value to this field will be considered as a change, regardless of whether the new value is the same as the previous one.</p><p>However, there is another solution — when the form stops thinking, it can set <strong>userName</strong> to <strong>null</strong> and the user will have to start typing a new name:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/17816e2212fa63f121e9562d57b0e43c/href">https://medium.com/media/17816e2212fa63f121e9562d57b0e43c/href</a></iframe><p>Now let’s think about a situation when a user is impatient and wants to get the result immediately. Well, let’s let him press <strong>Enter</strong> ((keydown.enter)=&quot;onEnter()&quot;) to get the immediate result:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fc9ce3c314b76931ca47ef82bf745fe4/href">https://medium.com/media/fc9ce3c314b76931ca47ef82bf745fe4/href</a></iframe><p>It would be nice to know how much time to wait if user does not press <strong>Enter</strong> — some kind of countdown counter would be very useful:</p><pre>&lt;h1 *ngIf=&quot;isThinking&quot;&gt;Thinking ({{countdown}} sec)...&lt;/h1&gt;</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/452b47701553c99f1c86834278478413/href">https://medium.com/media/452b47701553c99f1c86834278478413/href</a></iframe><p>and it is how it looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*JA8F3SPyo-IYb_BGgRUOKA.gif" /></figure><p>The countdown is also should be reset each time a new greeting is ready. It prevents the situation when the user immediately presses [Enter] and the countdown remains <strong>3</strong> at this moment — after that it stops working, since its value will never change again. For simplicity lets reset all the fields that depend on “Is Thinking” flag:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f6360347369b98a15752571a6251fbf6/href">https://medium.com/media/f6360347369b98a15752571a6251fbf6/href</a></iframe><h3>Change Detection</h3><p>Obviously, the countdown woks asynchronously and this fact does not cause any issue with the Angular change detection as long as the component detection strategy is <strong>Default</strong>. However, if the strategy is <strong>OnPush</strong>, then nothing can tell the component that its state is changing while the countdown is in progress.</p><p>Fortunately, we’ve already defined a callback function which is called each time when the component state has just changed, so the only thing which is required is adding an explicit change detection there:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bc50cbec476a81eeef71edbd9c3e9f65/href">https://medium.com/media/bc50cbec476a81eeef71edbd9c3e9f65/href</a></iframe><p>Now it works as expected even with <strong>OnPush</strong> detection strategy.</p><h3>Output Properties</h3><p>The library detects all component event emitters and calls them when a bound component field has just changed. By default the binding is performed using <strong>Change</strong> suffix for the event emitters:</p><pre>greeting:  string;</pre><pre>@Output()<br>greetingChange = new EventEmitter&lt;string&gt;();</pre><h3>Shared State</h3><p>Typically, when a component is destroyed (e.g. hidden by *<strong>ngIf</strong>) then all still pending asynchronous operations initiated by that component end in nothing. However, the library allows extracting a component state with its transitions into a separate object which can exist independently on the component. More other, such object can be shared between several components simultaneously!</p><p>Let’s convert the greeting form component <a href="https://stackblitz.com/edit/set-state-greet?file=src/app/services/greeting-service.ts">into a service</a>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/321127563f4c1d8190bb354fc6f3040d/href">https://medium.com/media/321127563f4c1d8190bb354fc6f3040d/href</a></iframe><p>and add it to <a href="https://stackblitz.com/edit/set-state-greet?file=src/app/app.module.ts">the module providers</a>.</p><p><strong><em>includeAllPredefinedFields</em></strong><em> means that all fields that have some initial value (even if it is </em><strong><em>null</em></strong><em>) will be automatically included into state objects.</em></p><p>To utilize the service inside a component, follow these steps:</p><ol><li>Inject the service instance into the component</li><li>Point the state tracker to the service instance</li><li>Declare component fields which will be bound to the corresponding service field</li><li>Subscribe to the service state changes — it is necessary when the explicit change detection is required or change detection strategy is “On Push”</li></ol><p>After these steps have been taken, the component will look <a href="https://stackblitz.com/edit/set-state-greet?file=src/app/complex-greeting-form/complex-greeting-form.component.ts">like this</a>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8fa3a42ad1a1d26afeb9251a8c2ab194/href">https://medium.com/media/8fa3a42ad1a1d26afeb9251a8c2ab194/href</a></iframe><p>The service instance is passed into <strong>initializeStateTracking</strong> function (using @StateTracking() decorator is also possible but it would take more efforts) which returns a state tracking handler that provides some methods to control the tracking behavior.</p><p>The subscription is required to call <strong>onStateApplied</strong> callback function when the service state is changed or to call a local transition function which depends on the shared state. If a component uses the default change detection strategy and there are no local transition functions, then subscription is not required.</p><p>Do not forget to unsubscribe it when the component is destroyed to avoid memory leaks. Alternatively, you can call <strong>handler.release()</strong> or <strong>releaseStateTracking(this)</strong> functions to release component subscriptions, but these methods also cancel pending asynchronous operations, which is not always desirable.</p><h3>Complex Shared State</h3><p>The library allows using shared states not only in components, but also in others services.</p><p>Let’s create <a href="https://stackblitz.com/edit/set-state-greet?file=src/app/services/greeting-log-service.ts">a service which will will log all greetings and simulate sending them to a server</a>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ac7bc66a833fec509f487b5bc39df55/href">https://medium.com/media/2ac7bc66a833fec509f487b5bc39df55/href</a></iframe><p>On each <strong>greeting</strong> field value change it will be added to <strong>log</strong> array. <strong>logVersion</strong> will be increased each time the array is changed to provide change detection without making <strong>log</strong> array immutable:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ffcc74874531d21e36c4d9546f0ae638/href">https://medium.com/media/ffcc74874531d21e36c4d9546f0ae638/href</a></iframe><p>The service will not send new greetings immediately, it will wait some time to collect a bunch of changes:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/401be61695521e442c6774d324419f93/href">https://medium.com/media/401be61695521e442c6774d324419f93/href</a></iframe><p>And finally saving:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bac974f2335737a6e144e2d2711335f5/href">https://medium.com/media/bac974f2335737a6e144e2d2711335f5/href</a></iframe><p>This transition function differs from the others — it is asynchronous.</p><ol><li>It decorated with <strong>WithAsync</strong> instead of just <strong>With</strong>.</li><li>The decorator has a concurrent launch behavior specification (OnConcurrentLaunchPutAfter in this case)</li><li>Instead of a current state object it receives a function which returns a current state at the moment it called.</li></ol><p>In the same way, we can implement greeting deleting and restoring , but I will skip this part, since there is nothing new in it.</p><p>As a result, our form will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*MENWu-4_LwsIB_9oswPA7w.gif" /></figure><p>—</p><p>We’ve just reviewed an example of a user interface with a relatively complex asynchronous behavior. However, it turns out that implementing this behavior is not that difficult using the concept of a series of immutable states. At least it can be considered as an alternative to RxJs.</p><p>—</p><ol><li>Link to the code: <a href="https://stackblitz.com/edit/set-state-greet">https://stackblitz.com/edit/set-state-greet</a></li></ol><p>2. Link to the previous article: <a href="https://itnext.io/angular-components-with-extracted-immutable-state-86ae1a4c9237?sk=3d9422a57d8ac49a4b1c8de39d6fc0b3">Angular Components with Extracted Immutable State</a></p><p>3. Link to ng-set-state source code: <a href="https://github.com/0x1000000/ngSetState">https://github.com/0x1000000/ngSetState</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e2b988540407" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/angular-components-state-tracking-with-ng-set-state-e2b988540407">Angular Components State Tracking with ng-set-state</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Writing SQL in C# or When You should not use ORM]]></title>
            <link>https://itnext.io/writing-sql-in-c-or-when-you-should-not-use-orm-5800a868db43?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/5800a868db43</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[sql-server]]></category>
            <category><![CDATA[query-builder]]></category>
            <category><![CDATA[sql]]></category>
            <category><![CDATA[dotnet]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Mon, 22 Feb 2021 16:45:08 GMT</pubDate>
            <atom:updated>2025-03-07T00:06:28.769Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*ANPmPrnM8US80_Ogy2zasA.png" /></figure><p>I noticed that when it becomes necessary to work with SQL databases in .Net applications, developers often chose some ORM library (.Net Entity Framework in most cases) without even considering other alternatives. This is a reasonable decision at first sight, since for popular ORM libraries there are many tutorials, great toolkit, and a lot of experienced developers. However, it is not always a good choice — I would at least consider other options if your application:</p><ol><li>Mainly works with fact relationships rather than objects</li><li>Requires using dynamic (not predefined) queries</li></ol><h3>Fact Relationships</h3><p>If your application mainly implements use cases similar to these ones:</p><p>1) “Give me the list of employees with the highest salary broken down by department”</p><p>2) “Give a discount to all customers registered in April”</p><p>3) “Reduce the price of T-shirts from last year’s collection by 20%”</p><p>then your application is focused on fact relationships rather than objects since all these scenarios involve handling an unpredictable amount of data. For example, organization might have 2 departments and 30 employees or hundreds of departments and hundreds of thousands of employees. If some ORM is used, it is assumed that all the data is loaded into memory, then analyzed and, in the case of write operations, uploaded back into the SQL database. Obviously, this cannot but affect performance.</p><p><em>Note. Modern ORM libraries have many ways to solve the performance problems such as LINQ expressions convertible to SQL, lazy loading, etc. But we must remember that these are just tricks that partially mitigate the conceptual issue and problems inevitably arise at some point.</em></p><p>On the other hand, SQL is specially designed to deal with fact relationships and the scenarios described above could be implemented with a couple relatively simple expressions. Obviously, it makes sense to use pure SQL without any ORMs here, but what options do we have? Not so many. The common ones will be:</p><p>1) Stored Procedures</p><p>2) Text based queries</p><p>3) Some LINQ based query builders (e.g. “LINQ to DB”)</p><p>4) <a href="https://github.com/0x1000000/SqExpress">My library “SqExpress” </a>:)</p><h3>Stored Procedures</h3><p>Stored procedures are the first thing that comes to mind when you need to use the full power of native SQL, but this approach has several serious disadvantages:</p><p>1) <strong>Difficulties in maintenance</strong> — it is always necessary to make sure that the .Net code is synchronized with code of stored procedures in all database instances that your application works with. This means that you are doomed to mess with migration scripts in almost every deployment and inevitably something will go wrong at some point.</p><p>2) <strong>SQL is a great query language, but a very bad programming language</strong> — Once you start writing stored procedures, it will be difficult to resist the temptation to move as much logic into them as possible, because it is such an easy way to solve performance problems and quickly fix issues in application design. But the downside is that you will not be able to break your logic into small modules and test them in isolation (how often I have seen “super” procedures for 5 thousand lines with hundreds of variables inside)</p><p>3) <strong>Copy-paste</strong> — The code in procedures is very difficult to reuse (functions, however, partly solve this problem), so some common logic will be duplicated in many procedures.</p><p>4) <strong>It is difficult to implement batch processing</strong>. <em>UpdateUserById</em> — it is the typical name for a stored procedure. But what if I have 100 users? No problem! Let’s call the procedure 100 times! The only problem is that it will take 100 times longer (Some databases support Table-Valued Parameters, but such parameters are difficult to use and maintain).</p><p>5) Stored procedures don’t help if you need dynamic queries</p><p>6) If you actively use stored procedures, then migrating to another SQL database will be incredibly difficult.</p><h3>Text based queries</h3><p>Queries resulting from simple string concatenation are pure evil. Such code is difficult to write, read, and maintain. Security is also a huge issue — Sql Injections are still relevant today.</p><p>However, surprisingly, there are some positive aspects to this approach:</p><p>1) You can use the approach in addition to any other one</p><p>2) It is still the most popular way to create dynamic queries which is available to everyone.</p><h3>LINQ based query builders</h3><p>Such query builders (e.g. <a href="https://linq2db.github.io/">“LINQ to DB”</a>) can be a good alternative when you need reach SQL abilities. “LEFT”, “RIGHT”, “FULL”, “CROSS” JOINS etc. are no longer a problem — you can express them directly in C# code (using LINQ):</p><pre>//Full Join<br>var query =<br>    from c in db.Category<br>    from p in db.Product.FullJoin(pr =&gt; pr.CategoryID == c.CategoryID)<br>    where !p.Discontinued<br>    select c;</pre><p><em>CTEs are also supported</em></p><pre>//CTE<br>var employeeSubordinatesReport  =<br>   from e in db.Employee<br>   select new<br>   {<br>      e.EmployeeID,<br>      e.LastName,<br>      e.FirstName,<br>      NumberOfSubordinates = db.Employee<br>          .Where(e2 =&gt; e2.ReportsTo == e.ReportsTo)<br>          .Count(),<br>      e.ReportsTo<br>   };<br><br>var employeeSubordinatesReportCte = employeeSubordinatesReport<br>                                       .AsCte(&quot;EmployeeSubordinatesReport&quot;);</pre><pre>var result =<br>   from employee in employeeSubordinatesReportCte<br>   from manager in employeeSubordinatesReportCte<br>                      .LeftJoin(manager =&gt; employee.ReportsTo == manager.EmployeeID)<br>   select new<br>   {<br>      employee.LastName,<br>      employee.FirstName,<br>      employee.NumberOfSubordinates,<br>      ManagerLastName = manager.LastName,<br>      ManagerFirstName = manager.FirstName,<br>      ManagerNumberOfSubordinates = manager.NumberOfSubordinates<br>   };</pre><p>However, when it comes to dynamic queries, LINQ is not the best solution. Theoretically it is possible to change the expression but it is not a simple action.</p><h3>SqExpresss</h3><p>For many years I was unhappy working with SQL from .Net, but then I wrote <a href="https://github.com/0x1000000/SqExpress">my own library (SqExpress)</a> (<a href="https://www.youtube.com/watch?v=Zd-fCb8NimA">Video Tutorial on Youtube</a>) that allows me to write C # code as close to SQL as possible. It does not use LINQ — query building is implemented through helper functions and operator overloading. As a result, there are no problems with dynamic queries. Here’s an example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4df8c81857e2bf0074952980e60ac463/href">https://medium.com/media/4df8c81857e2bf0074952980e60ac463/href</a></iframe><h3><strong>Still ORM?</strong></h3><p>There is one more question left: “When ORM is a good solution?” Well.. let’s just invert those conditions under which ORM is not recommended to use:</p><ol><li>In the vast majority of scenarios, you can accurately predict the number of rows in database tables that will be read or modified (that means that all the data can be mapped to objects)</li><li>No frequent need in dynamic queries</li></ol><p>If these conditions are met, then most likely ORM is the right choice.</p><p>—</p><p>I hope this short article will help you decide which way of working with a SQL database is best for your application, or at least you will reflect and don’t make hasty decisions.</p><p>Links:</p><ul><li><a href="https://github.com/linq2db/linq2db">linq to db on github</a></li><li><a href="https://github.com/0x1000000/SqExpress">SqExpress on github</a> (<a href="https://www.youtube.com/watch?v=Zd-fCb8NimA">Video Tutorial on Youtube</a>)</li><li><a href="https://itnext.io/syntax-tree-and-alternative-to-linq-in-interaction-with-sql-databases-656b78fe00dc?source=friends_link&amp;sk=f5f0587c08166d8824b96b48fe2cf33c">“Syntax Tree and Alternative to LINQ in Interaction with SQL Databases”</a>- my previews article related to this topic</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5800a868db43" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/writing-sql-in-c-or-when-you-should-not-use-orm-5800a868db43">Writing SQL in C# or When You should not use ORM</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[No need to wait for .Net 5 to start using code generation with Roslyn]]></title>
            <link>https://itnext.io/no-need-to-wait-for-net-5-to-start-using-code-generation-with-roslyn-f2317b438a6c?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/f2317b438a6c</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[roslyn]]></category>
            <category><![CDATA[c-sharp-programming]]></category>
            <category><![CDATA[code-generation]]></category>
            <category><![CDATA[dotnet]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Tue, 03 Nov 2020 15:18:44 GMT</pubDate>
            <atom:updated>2020-11-03T15:31:45.405Z</atom:updated>
            <content:encoded><![CDATA[<h3>No need to wait for .Net 5 to start using code generation with Roslyn</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/933/1*i4wapBXiApzZtOnS5upiag.png" /></figure><p>Recently, when I was reviewing the new features that are going to be included in .Net 5, I came across an interesting one — <a href="https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/">C# Source Generators</a>. This feature especially interested me since I have been using a similar approach for the last… 5 years and what Microsoft proposes is simply a deeper integration of this approach into the build process.</p><p>Further I’ll share my experience using Roslyn in code generation and I think this will help you better understand what exactly Microsoft offers and when you can use it.</p><p>First, let’s look at a typical code generation scenario. You have some external source of information such as a database, a JSON description of some REST service, another assembly (via reflection) etc. And using this information you can generate various types of source code such as DTOs, db model classes or proxies to REST services.</p><p>However, sometimes there are situations when there is no any external source of information and everything you need is contained in the source code of the project itself, where you want to add some generated code.</p><p>Coincidentally, I recently published an open source project that has an example of such a situation. In the project there are <a href="https://github.com/0x1000000/SqExpress/tree/main/SqExpress/Syntax">more than 100 classes</a> that represent SQL syntax tree nodes and I needed to create visitors which would <a href="https://github.com/0x1000000/SqExpress/blob/main/SqExpress/SyntaxTreeOperations/Internal/ExprWalker.cs">traverse</a> and <a href="https://github.com/0x1000000/SqExpress/blob/main/SqExpress/SyntaxTreeOperations/Internal/ExprModifier.cs">modify</a> tree objects (You can find more information about the project in my previous article <a href="https://itnext.io/syntax-tree-and-alternative-to-linq-in-interaction-with-sql-databases-656b78fe00dc?source=friends_link&amp;sk=f5f0587c08166d8824b96b48fe2cf33c">Syntax Tree and Alternative to LINQ in Interaction with SQL Databases</a>).</p><p>The reason why the code-generation is a good choice here is that each time I make even a small change to the classes I need to remember to modify the visitors and these changes must be done very carefully. However, I cannot use reflection for the code generation, since the assembly containing the new changes simply does not exist yet, and if these changes are not compatible with the previous version and lead to compilation errors, then this assembly will never appear until I manually fix all the errors.</p><p>At first glance, this problem has no solution, but in fact, I can use the Roslyn compiler to solve it. I can pre-compile the model classes in advance and get information similar to what I could get via the reflection.</p><p>Let’s create a simple console application and add <a href="https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp">Microsoft.CodeAnalysis.CSharp</a> package.</p><p><em>Note: Theoretically it could be done in t4 but I prefer not to struggle with dependencies and strange t4 syntax.</em></p><p>First, we need to read all the cs files that contain the model classes and extract syntax trees from them:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b7da807f9d7fe89f0dfbb1efade3ba6a/href">https://medium.com/media/b7da807f9d7fe89f0dfbb1efade3ba6a/href</a></iframe><p>The trees contain a lot of information about the source code from text perspective (class names, method names, etc.), but often this information is not enough as we want to know what the text means, so we need to ask Roslyn to analyze the syntax trees and get some semantic data:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2d97be429de9a19e4a473cc1d0a96c8/href">https://medium.com/media/b2d97be429de9a19e4a473cc1d0a96c8/href</a></iframe><p>Using the semantic data we can get an object of <strong>INamedTypeSymbol</strong> type:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/adbebf6effd820922015fde2011def72/href">https://medium.com/media/adbebf6effd820922015fde2011def72/href</a></iframe><p>which can provide information about class constructors and properties:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae88b393de99645f73ec18e8947eb3a0/href">https://medium.com/media/ae88b393de99645f73ec18e8947eb3a0/href</a></iframe><p>Since all the model classes are immutable, all meaningful properties have to be set via theirs constructors, so let’s iterate all the constructors parameters and get their types:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0d242618180fcb28899b2ebc2f58b5a5/href">https://medium.com/media/0d242618180fcb28899b2ebc2f58b5a5/href</a></iframe><p>Now it needs to analyze the parameter type and find out the following things:</p><ol><li>Is the type a list?</li><li>Is the type Nullable (the project uses “<a href="https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references">Nullable reference types”</a>)?</li><li>Whether the type inherits from the base type (in our case, the interface) for which we create “Visitors”.</li></ol><p>The semantic model provides answers to these questions:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/72068fabe4e99366bc2c13c0a462b1c0/href">https://medium.com/media/72068fabe4e99366bc2c13c0a462b1c0/href</a></iframe><p><em>Note: The method “AnalyzeSymbol” extracts an actual type from collections and Nullables:</em></p><pre>List&lt;T&gt; =&gt; T (list := true) <br>T? =&gt; T (nullable := true) <br>List&lt;T&gt;? =&gt; T (list := true, nullable := true)</pre><p>Checking a base type in the semantic model is more complex than if you were using the reflection, but it is also possible:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3abde4c5297f68030a8701787ad77619/href">https://medium.com/media/3abde4c5297f68030a8701787ad77619/href</a></iframe><p>Now we can put all the information in a simple container:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b3bdb28aa6b56176084aad62e7f455a0/href">https://medium.com/media/b3bdb28aa6b56176084aad62e7f455a0/href</a></iframe><p>and use it in the code generation to create <a href="https://github.com/0x1000000/SqExpress/blob/main/SqExpress/SyntaxTreeOperations/Internal/ExprModifier.cs">something like this</a>.</p><p>In my project, I run the code generation as a console utility, but in .Net 5 you will be able to embed this generation into the project as a class marked with a special attribute that will be automatically run at compile time to add missing parts of the code. This is certainly more convenient than a standalone utility, but the idea is similar.</p><p>Finally, I want to say that you shouldn’t take this new feature of .Net 5 as an incredible innovation that will fundamentally change the approach to dynamic code generation that is used in libraries such as AutoMapper, ASP.Net Core, etc. (I’ve heard such opinions) It will not! The fact is that the code-generation works in a static context where everything is known in advance, but, for example, AutoMapper does not know what classes it will work with and it still will have to dynamically emit code. However, there are situations when such code generation is very useful (I described one of them in this article). So it’s worth knowing about this feature and understanding its principles and limitations.</p><p>(<a href="https://github.com/0x1000000/SqExpress/blob/main/SqExpress.GenSyntaxTraversal/Program.cs">link to the source code on github</a>)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f2317b438a6c" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/no-need-to-wait-for-net-5-to-start-using-code-generation-with-roslyn-f2317b438a6c">No need to wait for .Net 5 to start using code generation with Roslyn</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Syntax Tree and Alternative to LINQ in Interaction with SQL Databases]]></title>
            <link>https://itnext.io/syntax-tree-and-alternative-to-linq-in-interaction-with-sql-databases-656b78fe00dc?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/656b78fe00dc</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[sql]]></category>
            <category><![CDATA[sql-server]]></category>
            <category><![CDATA[query-builder]]></category>
            <category><![CDATA[dotnet]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Thu, 22 Oct 2020 19:14:57 GMT</pubDate>
            <atom:updated>2020-10-26T10:27:41.760Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/684/1*1podaI9L-C-sxKmiQlMdfg.png" /></figure><p>It was a legacy enterprise project and I was asked to improve its “advanced” filtering capabilities.</p><p>Before they had something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/699/1*BqOVDTfLdKUtF98_VQSfgQ.png" /></figure><p>But wanted something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/879/1*6dMU_H2Kz5bT5JbHB-jj_w.png" /></figure><p>Let’s skip the UI part and focus on the data access layer. Like 99% of similar projects this one used a sql database (MS SQL but it is does not matter) and this project belonged to the part of the similar projects that does not struggle with Entity Framework but puts all the logic in stored procedures. The procedure which performed the “advanced” search looked like that:</p><pre>CREATE PROCEDURE dbo.SomeContextUserFind<br>    (<a href="http://twitter.com/ContextId">@ContextId</a> int, <a href="http://twitter.com/Filter">@Filter</a> nvarchar(max)) AS<br>BEGIN</pre><pre>DECLARE <a href="http://twitter.com/sql">@sql</a> nvarchar(max) = <br>    N&#39;SELECT U.UserId, U.FirstName, U.LastName<br>    FROM [User] U<br>    INNER JOIN [SomeContext] [C]<br>      ON ....<br>    WHERE [C].ContextId = <a href="http://twitter.com/p1">@p1</a> AND &#39; + <a href="http://twitter.com/Filter">@Filter</a>;</pre><pre>EXEC sp_executesql <br>    <br>    <a href="http://twitter.com/sql">@sql</a>,<br>    N&#39;<a href="http://twitter.com/p1">@p1</a> int&#39;,<br>    <a href="http://twitter.com/p1">@p1</a>=<a href="http://twitter.com/ContextId">@ContextId</a><br>END</pre><p>and the code that generated the filter string looked something like that:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5db3b3d7f82f8481d16f72e2bba27c2d/href">https://medium.com/media/5db3b3d7f82f8481d16f72e2bba27c2d/href</a></iframe><p>Of course it is not the greatest code you have ever seen, but unfortunately legacy projects (or even not yet legacy) often are full of similar things. Anyway, it is what it is and it should be somehow improved.</p><p>The first thought that came to my mind is just adding more fields into the “FilterItem” and make the building logic more complex, but I quickly realized that it a road to nowhere — it would be extremely difficult to maintain such code, and I would never achieve the desired functionality.</p><p>At that point, I remembered the “abstract syntax tree”, which is obviously the best choice in this case, and now I am going to explain what it is and how it helps.</p><p><strong>Abstract Syntax Tree</strong></p><p>First, let’s look at the filter strings we’re going to create, for example this one:</p><pre>[FirstName]=&#39;John&#39; AND ([LastName]=&#39;Smith&#39; OR [LastName]=&#39;Doe&#39;)</pre><p>And here we can notice some structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*RXzedZCI-oEQ0nA6mpVz7A.png" /></figure><p>This structure is a tree and that means that we can create several simple classes which will describe it:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-qQgBQarJnyVGc-7W4ussg.png" /></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/531c60756f863765e09b722c514a5580/href">https://medium.com/media/531c60756f863765e09b722c514a5580/href</a></iframe><p>Using the classes, we can create an object which would represent the original filter:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5df991517f27be3f4de28bef72838761/href">https://medium.com/media/5df991517f27be3f4de28bef72838761/href</a></iframe><p>In fact, this structure, called the “Abstract Syntax Tree”, can be used to represent more complex queries, but they will all have a single “root” that can be stored in a single object.</p><p>“Abstract Syntax Tree” is a result of parsing a phrase of some formal language (language of Boolean expressions in our case) with defined syntax rules. Such rules have a specific notation. For example the rules of our simple language (subset of boolean expressions) can be written as:</p><pre>&lt;eqPredicate&gt; ::= &lt;column&gt; = &lt;str&gt;<br>&lt;or&gt; ::= &lt;eqPredicate&gt;|or|&lt;and&gt; OR &lt;eqPredicate&gt;|or|&lt;and&gt;<br>&lt;and&gt; ::= &lt;eqPredicate&gt;|(&lt;or&gt;)|&lt;and&gt; AND &lt;eqPredicate&gt;|(&lt;or&gt;)|&lt;and&gt;</pre><p><em>Note: “Abstract” means that the syntax do not describe all the language details, for instance, grouping parentheses, extra spaces etc.</em></p><p>Parsing is a separate huge topic in and of itself, and it’s not that important right now since we already have syntax trees ready, so let’s focus on what we can do with them.</p><p><strong>SQL Code Generation</strong></p><p>Obviously, the most important task for us is converting the syntax tree back to text and we have several ways to do that.</p><p>The first way is to use pattern matching, which is pretty straightforward:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d8b38856578f28d7465e3c45b0ee4e00/href">https://medium.com/media/d8b38856578f28d7465e3c45b0ee4e00/href</a></iframe><p>As a result, the builder will contain the following line:</p><pre>[FirstName]=&#39;John&#39; AND ([LastName]=&#39;Smith&#39; OR [LastName]=&#39;Joe&#39;)</pre><p>It seems this is what we need!</p><p><strong>Visitor</strong></p><p>Although I have a passion for functional programming, in this case the object-oriented approach may provide a more efficient solution — I’m talking about the “Visitor” pattern. The idea of this pattern is that we do not try to determine a type of an object, but give it a list of all possible actions (in the form of an interface) and the object itself chooses the action that is most appropriate for its type. Let’s define the list:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d084ec703c6d76f28fd5c572437d2d97/href">https://medium.com/media/d084ec703c6d76f28fd5c572437d2d97/href</a></iframe><p>and any object (of our structure) can accept the selection:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eab89fe7a2918a0ea4ab171f2f4a2a73/href">https://medium.com/media/eab89fe7a2918a0ea4ab171f2f4a2a73/href</a></iframe><p>Now we can extract the generation of sql code into a separate class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/15668efad919f8933f5d93db26d1cc35/href">https://medium.com/media/15668efad919f8933f5d93db26d1cc35/href</a></iframe><p>And use it as follows:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d0e731b7e65f1c9c5f3fb249e344a5c9/href">https://medium.com/media/d0e731b7e65f1c9c5f3fb249e344a5c9/href</a></iframe><p>As a result, we will get the desired string:</p><pre>[FirstName]=&#39;John&#39; AND ([LastName]=&#39;Smith&#39; OR [LastName]=&#39;Joe&#39;)</pre><p>Using the “Visitor” pattern has several advantages over the pattern matching. So, for example, the selection of concrete types is always exhaustive since adding a new type to the structure always leads to a change in the <strong>IExprVisitor</strong> interface and, as a result, the need to extend all its implementations (otherwise there will be compilation errors).</p><p><strong>Traversal and parentheses</strong></p><p>There are several aspects to pay attention to in this algorithm.</p><p>First, how does it work at all?</p><p>In fact, here we are doing a depth-first traversal of the syntax tree and the sql code is a trace of this traversal:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/969/1*v3O5mIMCE98mmBS7JyUXTw.png" /></figure><p>Second, what happens to the parentheses?</p><p>The point is that Boolean expressions have a certain order of evaluation. ‘AND’ operation is evaluated first, and ‘OR’ operation is evaluated second. The parentheses are needed to change this sequence, since any expression in parentheses has a higher priority in the evaluation. But in the syntax tree, the sequence of the evaluation is given by the structure itself (from branches to the root), so a separate type for parentheses is not required.</p><p><strong>Extension of the syntax</strong></p><p>In reality, of course, we also need other predicates, for example ‘Not Equal’ and to be able to use it, we just need to add a new class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2c428fd94af864c6abe7c9618281c312/href">https://medium.com/media/2c428fd94af864c6abe7c9618281c312/href</a></iframe><p>And since we have a new type, the compiler tells us that we need to implement the SQL code generation for it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/88993db64a0c419ffb9ff3329706c15a/href">https://medium.com/media/88993db64a0c419ffb9ff3329706c15a/href</a></iframe><p>We’ve created just a very simple set of Boolean predicates and MS SQL supports many more, but as you see you can easily add all the required language structures.</p><p>By the way, the SQL Server documentation has all the <a href="https://docs.microsoft.com/en-us/sql/t-sql/queries/search-condition-transact-sql">SQL syntax</a> rules that are very useful:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*VzVFd-VQ_v4yayq0UOcQHA.png" /></figure><p><strong>Operator Overloading</strong></p><p>Obviously, creating syntax trees by calling the class constructors is not convenient at all. However, the C# operator overloading can help us with this.</p><p>Let’s do the following:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/62eb189d2e09b3a6694921f8c429c150/href">https://medium.com/media/62eb189d2e09b3a6694921f8c429c150/href</a></iframe><p>Now we can create a syntax tree in a very simple and clear way:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6e634bc5c714f210d0c03d23f42b8e26/href">https://medium.com/media/6e634bc5c714f210d0c03d23f42b8e26/href</a></iframe><p>And the result again will be:</p><pre>[FirstName]=&#39;John&#39; AND ([LastName]=&#39;Smith&#39; OR [LastName]=&#39;Doe&#39;)</pre><p><em>Note: C# does not allow overloading of the </em><strong>&amp;&amp;</strong><em> and </em><strong>||</strong><em> operators and actually it makes sense, since these operators stop further evaluation if the result is already known, but we need all the parts to build the syntax tree (it will be evaluated by the SQL database).</em></p><p><strong>What is Next</strong></p><p>We seem to have solved the problem with boolean filters, but what is about sorting and paging? It is also sometimes necessary to attach a sql view (or derived table) to filter (or sort) on a calculated field.</p><p>Not a problem! Let’s just implement all the <a href="https://docs.microsoft.com/en-us/sql/t-sql/queries/select-transact-sql">SQL SELECT</a> syntax:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/623/1*-dRhcWuBfITil785rSl2BA.png" /></figure><p>Of course, you do not need to do it by yourself since there are several libraries (<a href="https://github.com/0x1000000/SqExpress">for example mine</a>) where this is already implemented, so just consider this approach as an alternative way to interact with SQL databases.</p><p><strong>Alternative to LINQ</strong></p><p>What we’ve done with the operator overloading is somewhat similar to LINQ expressions, and in fact there are some actual similarities. The C# compiler generates syntax trees and then libraries such as Entity Framework or “LINQ to SQL” convert those trees to real SQL code. The main problem with this approach is that the compiler generates syntax tree of C# language, but we need SQL! Reflecting imperative C# into declarative SQL is not an easy task, and the results are often unpredictable.</p><p>I prefer a different approach — instead of using C # syntax as a basis, it can use real SQL syntax. And instead of the compiler, it can use operator overloading, extension methods and fluent builders.</p><p>With this approach,on the one hand, we get almost the same flexibility as if we were using stored procedures. On the other hand, we have strong typing, intellisense and business logic does not move to the database. And … no need to google how to do a left join using LINQ )</p><p>Another advantage is that the data update statements (INSERT, UPDATE, DELETE and even MERGE) can also be implemented in the same way, and there is no need to load thousands of records from the database to update a just single column.</p><p>This is an example of what can be done using real SQL syntax as a basis (t<a href="https://github.com/0x1000000/SqExpress#more-tables-and-foreign-keys">aken from here</a>):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d6a95e8ec078cf80cb10e3496dbd9571/href">https://medium.com/media/d6a95e8ec078cf80cb10e3496dbd9571/href</a></iframe><p><strong>Conclusion</strong></p><p>Syntax tree is a very powerful data structure that you will likely come across sooner or later. Probably these will be LINQ expressions, or maybe you will need to create a Roslyn analyzer, or maybe you want to create your own syntax yourself, like I did a few years ago in order to refactor one legacy project. In any case, it is important to understand this structure and be able to work with it.</p><p><a href="https://github.com/0x1000000/SqExpress"><em>Link to SqExpress</em></a><em> — a project that partially includes the code from this article.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=656b78fe00dc" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/syntax-tree-and-alternative-to-linq-in-interaction-with-sql-databases-656b78fe00dc">Syntax Tree and Alternative to LINQ in Interaction with SQL Databases</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Writing “Lazy Task” Using New Features of C# 7]]></title>
            <link>https://itnext.io/writing-lazy-task-using-new-features-of-c-7-7e9b3f2fda07?source=rss-7badc0087470------2</link>
            <guid isPermaLink="false">https://medium.com/p/7e9b3f2fda07</guid>
            <category><![CDATA[dotnet-core]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[csharp]]></category>
            <category><![CDATA[asyncawait]]></category>
            <dc:creator><![CDATA[Dmitry Tikhonov]]></dc:creator>
            <pubDate>Mon, 01 Jun 2020 13:10:24 GMT</pubDate>
            <atom:updated>2025-05-09T00:51:42.484Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*d0gOLynlOC6jEu8EY5Eq0A.png" /></figure><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fzq15I0QB6eM%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dzq15I0QB6eM&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fzq15I0QB6eM%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca087b2195a64250c1b97234f23815ea/href">https://medium.com/media/ca087b2195a64250c1b97234f23815ea/href</a></iframe><p>Almost 100% of asynchronous tasks that you deal with in your C# code are running or already completed regardless of whether you “await” them or not. This can be shown with the following example:</p><pre>static async Task Main()<br>{<br>    var task = GetValueAsync();<br>    await Task.Delay(500);<br>    Console.WriteLine(&quot;Awaiting...&quot;);<br>    Console.WriteLine(&quot;Result is: &quot; + await task);<br>}<br><br>static async Task&lt;int&gt; GetValueAsync()<br>{<br>    Console.WriteLine(&quot;Async Start&quot;);<br>    await Task.Delay(100);<br>    Console.WriteLine(&quot;Async End&quot;);<br>    return 42;<br>}</pre><p>Output:</p><pre>Async Start<br>Async End<br>Awaiting...<br>Result is: 42</pre><p>As you see <strong>GetValueAsync</strong> finished before <strong>await</strong> but what if the behavior is not desired and you do not want a task to start executing until there is at least one “awaiter”? Of course, you can use <strong>Lazy </strong>— a generic class from the <strong>System</strong> namespace:</p><pre>static async Task Main()<br>{<br>    var task = new Lazy&lt;Task&lt;int&gt;&gt;(GetValueAsync);<br>    await Task.Delay(500);<br>    Console.WriteLine(&quot;Awaiting...&quot;);<br>    Console.WriteLine(&quot;Result is: &quot; + await task.Value);<br>}<br><br>static async Task&lt;int&gt; GetValueAsync()<br>{<br>    Console.WriteLine(&quot;Async Start&quot;);<br>    await Task.Delay(100);<br>    Console.WriteLine(&quot;Async End&quot;);<br>    return 42;<br>}</pre><p>Output:</p><pre>Awaiting...<br>Async Start<br>Async End<br>Result is: 42</pre><p>However, there is another solution which will just slightly impact you client code — it is replacing of <strong>Task</strong> returned by your asynchronous function with <strong>LazyTask</strong> — a class that you can create by your own using the new C#7 feature — <strong>Generalized async return types</strong></p><p>As a result, your code will look like as follows:</p><pre>static async Task Main()<br>{<br>    var task = GetValueAsync();<br>    await Task.Delay(500);<br>    Console.WriteLine(&quot;Awaiting...&quot;);<br>    Console.WriteLine(&quot;Result is: &quot; + await task);<br>}<br><br>static async LazyTask&lt;int&gt; GetValueAsync()<br>{<br>    Console.WriteLine(&quot;Async Start&quot;);<br>    await Task.Delay(100);<br>    Console.WriteLine(&quot;Async End&quot;);<br>    return 42;<br>}</pre><p>Output:</p><pre>Awaiting...<br>Async Start<br>Async End<br>Result is: 42</pre><p>As you know C# compiler converts methods marked <strong>async</strong> into a state machine where each state represents a completion of an asynchronous operation marked <strong>await</strong>. <strong>Generalized async return types</strong> allow you to gain access to the state machine execution (I examined this mechanism in detail in <a href="https://habr.com/en/post/458692/">one of my previous articles</a>.) and in our case we just need to postpone the first step till we have at least one “awaiter”. It can be done by adjusting the <strong>Start</strong> method:</p><blockquote><a href="https://github.com/0x1000000/LazyTask/blob/master/LazyTask/LazyTaskMethodBuilder.cs">LazyTaskMethodBuilder.cs</a></blockquote><pre>public class LazyTaskMethodBuilder&lt;T&gt;<br>{<br>    public LazyTaskMethodBuilder() =&gt; this.Task = new LazyTask&lt;T&gt;();<br>    public void Start&lt;TStateMachine&gt;(<br>        ref TStateMachine stateMachine)..<br>    {<br>        //instead of stateMachine.MoveNext();<br>        this.Task.SetStateMachine(stateMachine);<br>    }<br>    ...<br>}</pre><p>Instead of starting the first step, the <strong>Start</strong> method just stores a link to the state machine inside the <strong>LazyTask</strong> object.</p><p>The first step now can be called only when we have the first “awaiter”:</p><blockquote><a href="https://github.com/0x1000000/LazyTask/blob/master/LazyTask/LazyTask.cs">LazyTask.cs</a></blockquote><pre>public void OnCompleted(Action continuation)                               {<br>    ...<br>    this._asyncStateMachine.MoveNext();<br>    ...<br>}</pre><p><em>Note: The interesting thing that the trick works even with methods which do not have any asynchronous calls inside (without “await” keyword).</em></p><p>That’s all!</p><p>In conclusion, I want to say that <strong>Generalized async return types</strong> is a powerful mechanism and <strong>LazyTask</strong> is just one the examples of how it can be utilized.</p><h4>Links</h4><ol><li><a href="https://github.com/0x1000000/LazyTask">Source code on Github;</a></li></ol><p><a href="https://habr.com/en/post/458692/">2. “Maybe” monad through async/await in C# (No Tasks!)</a> — an article where <strong>Generalized async return types</strong> are examined in detail;</p><p>3. <a href="https://youtu.be/zq15I0QB6eM">Video version with more details</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7e9b3f2fda07" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/writing-lazy-task-using-new-features-of-c-7-7e9b3f2fda07">Writing “Lazy Task” Using New Features of C# 7</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>