<?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 Marcio Nizzola - MVP on Medium]]></title>
        <description><![CDATA[Stories by Marcio Nizzola - MVP on Medium]]></description>
        <link>https://medium.com/@nizzola.dev?source=rss-f6e24590bee6------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*qJ-iGlv1YHEbacvKZ_CBaA.png</url>
            <title>Stories by Marcio Nizzola - MVP on Medium</title>
            <link>https://medium.com/@nizzola.dev?source=rss-f6e24590bee6------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 28 Jun 2026 00:51:35 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@nizzola.dev/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[Introducing TOON: An Optimized Serialization Format for AI and LLM Workloads]]></title>
            <link>https://medium.com/@nizzola.dev/introducing-toon-an-optimized-serialization-format-for-ai-and-llm-workloads-cbaacdd5167e?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/cbaacdd5167e</guid>
            <category><![CDATA[dotnet-core]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Tue, 11 Nov 2025 11:12:11 GMT</pubDate>
            <atom:updated>2025-11-11T11:12:11.806Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/286/0*irqX-TRwb6nQG7Qa" /><figcaption>Introducing TOON: An Optimized Serialization Format for AI and LLM Workloads</figcaption></figure><p>Hey there, readers! I’m NIZZOLA, a developer and AI enthusiast. Today, I’m excited to share a project I built specifically to optimize large language model (LLM) workflows and AI-driven applications: <strong>NIZZOLA.TOON.NET</strong>, a serializer for <strong>Token-Oriented Object Notation (TOON)</strong>. Designed with token efficiency in mind, TOON addresses the high costs and latency of traditional JSON when interacting with LLM APIs.</p><p>This article is based on the GitHub repository and highlights the <strong>key benefits</strong> of using this format, along with the <strong>ease of implementation</strong> using my .NET library. Let’s dive in!</p><h3>What is TOON?</h3><p><strong>Token-Oriented Object Notation (TOON)</strong> is a compact, token-efficient serialization format tailored for AI and LLM workloads. Unlike JSON, which is often bloated with braces, quotes, and commas, TOON minimizes token usage through smart strategies like optimized indentation, automatic tabular detection, and CSV-style compact arrays.</p><p>The result? A format that’s not only <strong>smaller</strong> but also <strong>human-readable</strong> — perfect for debugging, prompt engineering, and feeding structured data into models like GPT, Grok, or Claude. The full implementation is available in the .NET library, ready for production use.</p><h3>Key Benefits of Using TOON</h3><p>The standout advantage of TOON is its ability to <strong>reduce token consumption by ~30–60% compared to JSON</strong>. In LLM-powered systems where every token has a cost, this translates into real-world savings. Here are the core benefits:</p><ul><li><strong>Lower API Costs for LLMs</strong>: By sending fewer tokens to models like OpenAI or Grok, you directly reduce operational expenses. Ideal for high-volume or tabular data workflows.</li><li><strong>Faster End-to-End Response Times</strong>: Less data means quicker serialization, transmission, and processing — leading to improved latency and throughput.</li><li><strong>Superior Readability for Debugging</strong>: Despite its compactness, TOON uses clean indentation and structure, making it easy to inspect prompts and model outputs.</li><li><strong>Smart Tabular Detection</strong>: Automatically identifies homogeneous object lists and serializes them as a <strong>header + rows</strong> table. The more rows, the greater the savings!</li><li><strong>Flexible &amp; Extensible</strong>: Supports naming policies (camelCase, snake_case), streaming, async operations, and easy customization via attributes.</li></ul><p>In short, TOON is an evolution of data serialization — built for the era of token-based AI.</p><h3>Effortless Implementation with NIZZOLA.TOON.NET</h3><p>I designed the library with .NET developers in mind. The API mirrors System.Text.Json.JsonSerializer, so adoption is seamless. Let’s see how easy it is to get started.</p><h3>Quick Installation</h3><p>Add the package via NuGet:</p><pre>dotnet add package Nizzola.TOON.NET</pre><p>That’s it — you’re ready to serialize.</p><h3>Simple Usage Examples</h3><p>Basic serialization and deserialization:</p><pre>// Serialize<br>var toon = ToonSerializer.Serialize(obj, new ToonSerializerOptions <br>{ <br>    Indentation = 2, <br>    NamingPolicy = NamingPolicy.CamelCase <br>});<br><br>// Deserialize<br>var model = ToonSerializer.Deserialize&lt;MyModel&gt;(toon);</pre><p>Async and stream support:</p><pre>// Async serialization<br>await ToonSerializer.SerializeAsync(stream, obj, options);<br>// Async deserialization<br>var result = await ToonSerializer.DeserializeAsync&lt;MyModel&gt;(stream);</pre><p><strong>Pro Tips</strong>:</p><ul><li>Use Indentation = 2 for the best balance of readability and compactness.</li><li>Enable tabular detection for large, uniform lists to maximize savings.</li><li>Match NamingPolicy to your LLM’s expected conventions (e.g., camelCase for English prompts).</li></ul><p>You can also use [ToonIgnore] to skip properties and fine-tune behavior with ToonSerializerOptions.</p><h3>Before &amp; After: TOON vs JSON</h3><p>ScenarioJSONTOONSavingsSingle data type listVerbose, repetitive keysCompact header + rows~40%Mixed data typesFull object nestingSmart indentation, minimal quotes~30–50%</p><p>The more structured and repetitive the data, the bigger the win.</p><p>Test 1</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*naHWGjRGzUlwohdxeYaZBA.png" /></figure><p>Test 2</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AA59rPR5ZAriIBxiPy-1FA.png" /></figure><h3>Core Library Features</h3><p>SymbolComponentPurpose🔧ToonSerializerMain sync/async API✍️ToonWriterHigh-performance formatting engine⚙️ToonSerializerOptionsIndentation, naming, tabular detection🚫ToonIgnoreAttributeExclude properties</p><p>Built on StringBuilder with optimized reflection caching, the library ensures <strong>blazing-fast performance</strong>. It supports CLR types, JSON-to-TOON conversion, and streaming scenarios.</p><h3>Why Adopt TOON? Real-World Impact</h3><p>TOON isn’t just a format — it’s a strategic advantage for AI developers. With <strong>NIZZOLA.TOON.NET</strong>, you get:</p><ul><li>Immediate token savings → <strong>lower costs</strong></li><li>Faster pipelines → <strong>better performance</strong></li><li>Familiar .NET API → <strong>zero learning curve</strong></li><li>Production-ready, MIT-licensed, open-source</li></ul><p>Whether you’re building prompt pipelines, data processors, or agent systems, TOON helps you do more with less.</p><h3>Get Started Today</h3><p>Head over to the <a href="https://github.com/NIZZOLA/ToonSerializerDotnet">GitHub repo</a> to explore the code, examples, and benchmarks. The library is NuGet-ready and battle-tested for LLM workflows.</p><p>If you find it useful, consider supporting development with a coffee: <a href="https://www.buymeacoffee.com/nizzola">Buy me a coffee! ☕</a></p><p>Follow me for more dev &amp; AI content: <a href="https://www.linkedin.com/in/nizzola/">LinkedIn</a> | <a href="https://medium.com/@nizzola">Medium</a> | <a href="https://www.instagram.com/nizzola.dev/">Instagram</a> | <a href="https://linktr.ee/nizzola">Linktree</a></p><p>Thanks for reading! Have you tried TOON in your projects? Drop a comment below — I’d love to hear your thoughts! 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cbaacdd5167e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running Testcontainers on Github Actions When Making Pull Requests]]></title>
            <link>https://medium.com/@nizzola.dev/running-testcontainers-on-github-actions-when-making-pull-requests-d32c1e22c457?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/d32c1e22c457</guid>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[testcontainer]]></category>
            <category><![CDATA[csharp]]></category>
            <category><![CDATA[c-sharp-programming]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Wed, 24 Sep 2025 11:01:56 GMT</pubDate>
            <atom:updated>2025-09-24T11:01:56.251Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*0aDCkXCb-YHMhMpaqTPCbQ.png" /><figcaption>Running Testcontainers on Github Actions When Making Pull Requests</figcaption></figure><p>After the article about Testcontainers (if you missed it, here’s the link), a question arises: why don’t we validate our tests when creating a pull request?</p><p>How can we do this? Github Actions (<a href="https://www.freecodecamp.org/news/learn-to-use-github-actions-step-by-step-guide/">learn more</a>) allows you to create actions within GitHub to run scripts, such as unit test validation!</p><p>For this, I’ll use the same project I demonstrated in the Testcontainers article, creating a script to run the tests.</p><p>Since this project has multiple unit tests, I’ll focus initially only on the tests for the project that uses Testcontainers: “Store.Infra.Data.Sql.Tests.csproj”.</p><p>To get started, how about a little help from GitHub itself? In your repository, click the “Actions” icon to use the built-in setup assistant:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*wkxenMcAIzWvOVAI.png" /></figure><p>A template will be displayed for editing and filling in your project details:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*oBPNgKY9uTqOz8z1.png" /></figure><p>Now, just fill in the folders and names of your project items:</p><p>1 — Solution name<br>2 — Repeat the solution name<br>3 — Project name (or you could keep the entire solution if you want to test everything). In this case, I chose to test only one project!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*N1UzdzZnZwKQg1gC.png" /></figure><p>Done! Save by clicking the “Commit Changes” button at the top of the window. It will prompt you to create a pull request with these changes. At this point, since the pull request is created, the GitHub Actions process will automatically start, running the tests.</p><p>Note that in lines 7–10, the actions where the script will run are configured — specifically, for “push” to the “main” branch and “pull request” to the “main” branch. You can modify these for other scenarios if needed.</p><p>As a result, we see that the process ran successfully!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*zcC5REdBHLiO9lDP.png" /></figure><p>If we click on that execution line, we can see the general details:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Fo8cxY3MwlvTcBy_.png" /></figure><p>And if we click the “build” button, we can see each step of the execution flow:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*HFQ9OMUzQ1TYc73b.png" /></figure><p>To see the details of each step, just click on it:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*8YFqZMBvEfWcmodu.png" /></figure><p>Now we have a setup that runs tests every time a pull request is made to the “main” branch and validates whether it worked!</p><p>But everything looks too perfect — let’s cause some trouble! I’ll edit and remove an important line in the test project and create a new pull request.</p><p>As soon as the test pipeline runs, we can see something went wrong. The pull request shows that the test failed!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*n5YDs0z7kneLGVyH.png" /></figure><p>Let’s check Actions to see what happened. Right away, we see an execution history where one of them failed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*b3SGchbPLfRBJwxS.png" /></figure><p>Looking at the details, we can see where it failed. If we click, we can even see the error log:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*hpp6rx-fcqWpQNJ_.png" /></figure><p>We see it was in the test. Clicking will show the entire process so we can identify where it failed. Now we’ve found the problem — just fix it and create a new pull request!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*EcMQUyVnxcv6ZO_R.png" /></figure><p>Okay, I used my personal GitHub account, which has Actions enabled. But what if you don’t see the “Actions” button in your work repository? Simple — it needs to be enabled for the organization. For individual users, it’s free up to 2000 minutes per month! It’s time for the boss to open their wallet and enable GitHub Actions — the benefits pay for themselves and can prevent a pull request from breaking an application!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*U4ZIzm0id2YDHbT5.png" /><figcaption><em>Source: </em><a href="https://github.com/pricing"><em>Pricing · Plans for every developer</em></a></figcaption></figure><p>Did you like the article? Click the 👏 icon and follow me to see upcoming publications! If you like to see more publications see my networks into my linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d32c1e22c457" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Use Testcontainers for Repository Integration Testing in .NET]]></title>
            <link>https://medium.com/@nizzola.dev/use-testcontainers-for-repository-integration-testing-in-net-17a4781e3952?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/17a4781e3952</guid>
            <category><![CDATA[csharp]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[testcontainer]]></category>
            <category><![CDATA[dotnet-core]]></category>
            <category><![CDATA[containers]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Mon, 22 Sep 2025 11:01:52 GMT</pubDate>
            <atom:updated>2025-09-22T11:01:52.592Z</atom:updated>
            <content:encoded><![CDATA[<h3>Use Testcontainers for Repository Integration Testing in .NET</h3><p>Testing the implementation of a repository by validating the saving of elements in the database is not a very easy task, and working with Mocks or In-Memory Databases is not always possible either. If you mix the use of Entity Framework and Dapper or raw SQL commands via SqlClient, you’ll see that In-Memory won’t work.</p><p>This is where the Testcontainers library (<a href="http://Use Testcontainers for Repository Integration Testing in .NET">https://dotnet.testcontainers.org/</a>) comes in. It’s a library made for .NET but has equivalents for other languages, as shown in the image below (taken from the website). There’s even one for Java!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*5usAEWyvTqVuHJAg.png" /><figcaption>supported languages with testcontainers librarty</figcaption></figure><p>Jokes aside, I decided to test it in an application I already had, and to my surprise, it was very simple to use and quick to implement.</p><p>To start, I created a new unit test project for the SQL layer of my application, where I’ll test the Repository. First, I created a class where I’ll instantiate the context using the Docker container instance with the Microsoft SQL database.</p><p>My repository follows a very simple implementation pattern, adhering to this interface as shown in the source code below:</p><pre>public interface IBaseRepository&lt;T&gt; where T : class<br>{<br>    Task&lt;IEnumerable&lt;T&gt;&gt; GetAll();<br>    Task&lt;T&gt; GetOne(Guid id);<br>    Task&lt;bool&gt; Create(T model);<br>    Task&lt;bool&gt; Update(T model);<br>    Task&lt;bool&gt; Delete(Guid id);<br>}</pre><p>The Repository has the Context as a parameter in its constructor.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*TjPkvRg8EJyeicY6.png" /></figure><p>Therefore, our test will be based on the premise of creating a Docker instance where we’ll implement the “StoreContext” database and run the project’s migration so the database is created with all tables according to the last registered migration.</p><p>For this, we’ll create a class called ContainersFixture:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*xFvHrcL0lRQLYIQR.png" /></figure><p>In the code blocks, we see the InitializeAsync method:</p><p>a) The block that creates the container — in this case, several parameters are passed to configure the Docker instance. After instantiating the object, the StartAsync command is executed to initialize it.</p><p>b) After instantiating the container object, in block b, we define some variables retrieved from the container instance and build the connection string.</p><p>c) In block c, we set up the context, which will be used to interact with the database instance created inside Docker.</p><p>d) Now, the Migration command is executed to create all tables in the database.</p><p>This is the first step. Now, we only need two more methods, shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*efygkYtvPHqGKQN-.png" /></figure><ul><li>GetContext will be used to obtain the context instance to inject into the repository.</li><li>DisposeAsync will terminate and remove the container objects from memory, as well as pause Docker.</li></ul><p>Now, let’s write the unit tests! We start by creating a StoreRepositoryTests class, and in its constructor, we’ll instantiate the Fixture class as shown in the code below. The red-highlighted area shows the repository being loaded in the constructor:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*ewxJSmY7NGSpp4R9.png" /></figure><p>We also create a method to generate a Store instance within the class itself:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/435/0*x7lu-DD0buXzqtVa.png" /></figure><p>The CreateNew method creates an instance of the Store class (line 22), adds it to the database via the Create command (line 25), and then queries it using the repository’s GetOne method, reading the store’s ID (newstore.Id).</p><p>In lines 30 and 31, we verify:</p><ul><li>Whether the product was successfully retrieved (i.e., not null).</li><li>Whether the product name matches the initial instance’s name.</li></ul><p>Let’s write more tests in the class — one for the Delete command. In this method, we’ll create a new Store instance, add it to the database, and then delete it using the repository’s Delete method:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/0*DSMXwyzKkgY_XZdM.png" /></figure><p>A test for the Update command, where we create a Store instance via Create, read it using GetOne, and then perform an Update, changing the store’s name. This is later verified in lines 69 and 70 to ensure it matches the information retrieved again from the database in line 67:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/670/0*atP4P7MvnsJwd19g.png" /></figure><p>Now, just run the tests and validate the functionality! As soon as the container starts, you’ll see it appear in the Docker window (if you have Docker Desktop; otherwise, just run docker ps to see the instance running).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*Sx7zL5BktHvszwMk.png" /></figure><p>The Testcontainers library itself will handle the initialization and shutdown of the database instance in Docker after the tests finish.</p><p>So, what are we testing?<br>The StoreRepositoryTests class implements the unit tests for the StoreRepository, which in its constructor receives the context connected to the Test Container instantiated in ContainersFixture.</p><p>The class tests the repository’s CRUD operations — adding items, reading items from the database, deleting, and updating — ensuring the repository works as expected when connected to the database.</p><pre>public class StoreRepositoryTests<br>{<br>    private readonly IStoreRepository _storeRepository;<br>    public StoreRepositoryTests()<br>    {<br>        var fixture = new ContainersFixture();<br>        fixture.InitializeAsync().Wait();<br>        var dbContext = fixture.GetContext();<br>        _storeRepository = new StoreRepository(dbContext, new FakeLogger&lt;StoreRepository&gt;());<br>    }<br><br>    [Fact]<br>    public async Task CreateNew()<br>    {<br>        var newStore = CreateInstance();<br><br>        // Act<br>        var response = await _storeRepository.Create(newStore);<br><br>        // Assert<br>        var product = await _storeRepository.GetOne(Guid.Parse(newStore.Id));<br><br>        Assert.NotNull(product);<br>        Assert.Equal(newStore.Name, product.Name);<br>    }<br><br>    [Fact]<br>    public async Task Delete()<br>    {<br>        var newStore = CreateInstance();<br><br>        // Act<br>        var response = await _storeRepository.Create(newStore);<br><br>        // Assert<br>        var product = await _storeRepository.GetOne(Guid.Parse(newStore.Id));<br><br>        Assert.NotNull(product);<br>        Assert.Equal(newStore.Name, product.Name);<br><br>        var deleteResponse = await _storeRepository.Delete(Guid.Parse(newStore.Id));<br>        Assert.True(deleteResponse);<br>        var deletedProduct = await _storeRepository.GetOne(Guid.Parse(newStore.Id));<br>        Assert.Null(deletedProduct);<br>    }<br><br>    [Fact]<br>    public async Task Update()<br>    {<br>        var newStore = CreateInstance();<br><br>        // Act<br>        var response = await _storeRepository.Create(newStore);<br><br>        // Assert<br>        var product = await _storeRepository.GetOne(Guid.Parse(newStore.Id));<br><br>        product.Name = &quot;Updated Store Name&quot;;<br>        await _storeRepository.Update(product);<br>        var updatedProduct = await _storeRepository.GetOne(Guid.Parse(newStore.Id));<br><br>        Assert.NotNull(product);<br>        Assert.Equal(updatedProduct.Name, product.Name);<br>    }<br><br>    private StoreModel CreateInstance()<br>    {<br>        return new StoreModel<br>        {<br>            Id = Guid.NewGuid().ToString(),<br>            Name = &quot;Test Store&quot;,<br>            Phone = &quot;1234567890&quot;,<br>            Email = &quot;abc@test.com&quot;<br>        };<br>    }<br>}</pre><p>With this, we can perform many tests that were previously incompatible with InMemoryDatabase, which didn’t allow direct SQL commands or the execution of Procedures and Views.</p><p>This example covers the use of SQL Server, but as per the library’s documentation, there’s support for many others, as seen in the image below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*32ey89Do5BOdespZ.png" /><figcaption>available types of containers for TestContainers use</figcaption></figure><p>Did you like the article? Click the 👏 icon and follow me to see upcoming publications! If you like to see more publications see my networks into my linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><h4>References</h4><p><a href="https://dotnet.testcontainers.org/modules/mssql/">Microsoft SQL Server — Testcontainers for .NET</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=17a4781e3952" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sorting with GUID? Meet the New UUID v7 Now Available in .NET 9]]></title>
            <link>https://medium.com/@nizzola.dev/sorting-with-guid-meet-the-new-uuid-v7-now-available-in-net-9-9bda4ed341f3?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/9bda4ed341f3</guid>
            <category><![CDATA[unique-id]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[dotnet-core]]></category>
            <category><![CDATA[dotnet-9]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Fri, 19 Sep 2025 01:05:42 GMT</pubDate>
            <atom:updated>2025-09-19T01:05:42.303Z</atom:updated>
            <content:encoded><![CDATA[<h3>Sorting with GUID? Meet the New UUID v7 Now Available in .NET 9</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*K-fAS3Arv9bMa9uQ5Rgh6w.png" /><figcaption>Sorting with GUID? Meet the New UUID v7 Now Available in .NET 9</figcaption></figure><p>When we use Guid to define unique non-numeric keys in .NET with the Guid.NewGuid command, which generates a UUID v4, there’s an issue: they don’t follow a chronological order. This means we often need to rely on other fields, such as creation or update dates, to sort records when querying a database.</p><p>However, .NET 9 introduces an exciting solution — a new type called UUID v7, which incorporates a timestamp in its structure, enabling natural sorting.</p><h3>How to Create a UUID v7?</h3><p>Using .NET 9, you can generate a UUID v7 with the following command:</p><pre>var uuidWithDate = Guid.CreateVersion7();</pre><p>By generating multiple UUIDs with a 10-second interval between them, you can observe the difference:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/482/0*TGP8OLYNJC0iut1T.png" /></figure><p>The structure consists of blocks based on date and time, combined with random components, allowing the UUIDs to be sorted.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/469/0*0CDe3kAhSMVfinvD.png" /></figure><p>This provides 122 bits of entropy, with 6 bits reserved for version and variant information embedded somewhere in the middle. The key advantage is that UUIDs can be sorted by creation time, making them more suitable for databases than UUID v4.</p><h3>Controlling the Timestamp</h3><p>Can we control the generation with different dates and times? This is often necessary for testing purposes. How can we achieve that?</p><p>The method supports a TimeProvider to control the DateTimeOffset.UtcNow:</p><pre>var uuid = Guid.CreateVersion7(timeProvider.GetUtcNow());</pre><h3>Why is UUID v7 Better for Databases?</h3><ul><li><strong>Natural Sorting</strong>: Traditional databases often require additional columns to sort records by creation time. With UUID v7, sorting is inherent in the UUID itself, eliminating the need for extra columns.</li><li><strong>Optimized Indexing</strong>: Since UUID v7 is time-sortable, database indexing mechanisms can optimize data storage and retrieval, resulting in faster time-based queries.</li><li><strong>Concurrency and Distribution</strong>: Generating unique, sequential IDs in distributed systems can be challenging. UUID v7 can be generated simultaneously across multiple nodes without collision risks, making it ideal for distributed architectures.</li><li><strong>Lower Overhead</strong>: Unlike UUID v1, which could expose the machine’s MAC address (raising privacy concerns), UUID v7 avoids this issue, reducing the need for data masking or anonymization.</li><li><strong>Flexibility</strong>: Databases that support binary storage can store UUID v7 efficiently, and it can be easily encoded into other formats, such as strings, when needed.</li></ul><h3>What’s Next?</h3><p>UUID v7 is now available in .NET 9, which was released a few months ago. You can start using it in your applications today to leverage its benefits for sorting and database optimization.</p><p>Did you enjoy the article? Click the 👏 icon, share it with your friends, and follow me for more posts! Want to see more content? Check out my social media via my Linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><h3>References</h3><p><a href="https://github.com/dotnet/runtime/issues/103658?source=post_page-----551b5e18b3d1---------------------------------------">Extend System.Guid with a new creation API for v7 · Issue #103658 · dotnet/runtime</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9bda4ed341f3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Had trouble mocking ILogger in unit tests? Use FakeLogger]]></title>
            <link>https://medium.com/@nizzola.dev/had-trouble-mocking-ilogger-in-unit-tests-use-fakelogger-4c1678a86cf6?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/4c1678a86cf6</guid>
            <category><![CDATA[unit-test-framework]]></category>
            <category><![CDATA[mocking]]></category>
            <category><![CDATA[unit-test-tools]]></category>
            <category><![CDATA[dotnet]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Fri, 04 Apr 2025 13:02:10 GMT</pubDate>
            <atom:updated>2025-04-04T13:02:10.560Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*ui0dIi0jkDvwNrmceAWmqQ.png" /><figcaption>Had trouble mocking ILogger in unit tests? Use FakeLogger</figcaption></figure><p>For those who write unit tests using NSubstitute and .NET, it’s quite common to face challenges when testing log messages, since the Logger has some peculiarities that the NSubstitute library doesn’t handle very well.</p><p>There are numerous posts complaining about this on StackOverflow, where messages like the one below frequently appear:</p><pre>Message: NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching: <br> Log&lt;Object&gt;(Error, 0, Test Exception, &lt;null&gt;, Func&lt;Object, Exception, String&gt;) <br>Actually received no matching calls. <br>Received 1 non-matching call (non-matching arguments indicated with &#39;*&#39; characters): <br> Log&lt;Object&gt;(Error, 0, *Test Exception*, &lt;null&gt;, Func&lt;Object, Exception, String&gt;)</pre><p>Starting with .NET 8, Microsoft introduced the FakeLogger class to simplify unit testing for Logger!</p><p>The FakeLogger is an in-memory logger specifically designed for unit testing. It allows capturing and inspecting log messages generated by the code under test, making it easier to verify that logging is working correctly.</p><h3>What are the benefits?</h3><h4>Features:</h4><ul><li>Capture all log messages in memory.</li><li>Inspect these messages to verify if the code logs correctly.</li><li>Control log levels for more precise testing.</li></ul><h4>Benefits:</h4><ul><li>Easy to use.</li><li>Isolate the code under test.</li><li>Improve the quality of unit tests.</li><li>Avoid “reinventing the wheel,” as many solutions appear in posts with different implementations for mocking ILogger and solving this problem.</li></ul><h3>Practical Example</h3><h4>1- Install the package</h4><p>To install the package, use the <strong>NuGet Package Manager</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*6qZ4O5Vmi-FbSbKv.png" /></figure><p>or simply run the following command:</p><pre>dotnet add package Microsoft.Extensions.Diagnostics.Testing</pre><p>Once the package is installed, let’s look at the code:</p><p>In the test class, instantiate the FakeLogger as shown in the image below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*v8o118AqoV6m41TH.png" /></figure><p>After implementing the _logger object, note that it was passed when instantiating the StoreRepository object to act as the Logger for the class.</p><p>Now, you can write the unit tests. The importance of monitoring logs is to ensure that the correct messages are included in the return. See the example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*KJZHCqJ1PkhgyzmR.png" /></figure><ul><li><strong>Line 66</strong>: We verify that the Logger’s return is not null.</li><li><strong>Line 67</strong>: We check the number of items collected by the logger (messages that would be written).</li><li><strong>Line 68</strong>: We verify that the last log is of type “Error.”</li><li><strong>Line 69</strong>: We check if the last message contains the phrase stored in the CreateError variable of the StoreMessageConstants class.</li></ul><p>Now, you know the basics of retrieving log messages and working with them to ensure your service returns the expected outputs in error cases. If you want to dive deeper into this object, check out the references at the end of this post.</p><p>Did you like the article? Click the 👏 icon and follow me to see upcoming publications! If you like to see more publications see my networks into my linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4c1678a86cf6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Simplify Dependency Injection to Services and Repositories]]></title>
            <link>https://medium.com/@nizzola.dev/simplify-dependency-injection-to-services-and-repositories-caf4c3c2942f?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/caf4c3c2942f</guid>
            <category><![CDATA[dependency-injection]]></category>
            <category><![CDATA[repository-pattern]]></category>
            <category><![CDATA[dotnet]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Fri, 28 Mar 2025 22:36:52 GMT</pubDate>
            <atom:updated>2025-03-28T22:36:52.870Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*BQF1jS6sxv5I-mwzOn_n6A.png" /><figcaption>Simplify Dependency Injection to Services and Repositories</figcaption></figure><p>How many times are we writing code and come across that old implementation of dependency injection in the application, defining interface x service, or interface x repository, as below?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/0*N2NZ0HC670cNdM_a.png" /><figcaption>sample code of dependency injection configuration in program.cs</figcaption></figure><p>Firstly, we see that the implementation is in our application’s “program.cs” (class that is accessed at startup), in addition to making it increasingly larger as your project grows, it is very difficult to validate, in addition to the dependencies that can be configured in your specific project, facilitating code analysis.</p><p>Right away, let’s create a static class within the project where the repositories are and implement an Extension Method (don’t know what it is, see my <a href="https://medium.com/@marcionizzola/tenha-mais-qualidade-de-c%C3%B3digo-c-com-o-uso-de-extensions-methods-d66317867b1e">previous article</a>) that will isolate dependency injection in a specific class for that project.</p><p>Normally I use the name “DependencyInjectorHelper” but this is not a rule, you can use any name.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/274/0*Ol5GvyqXdsM_MUKX.png" /><figcaption>view of project folders and files</figcaption></figure><p>In this file we will implement the injection in a method that will be an Extension Method of the “IServiceCollection” interface, which is the object where the codes were created manually!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/0*gbmbu-DL64QIVL-T.png" /><figcaption>sample class with extension method configuring dependency injection</figcaption></figure><p>Note that in this method we use “this” transforming it into an extension method of the “IServicesCollection” interface, so this way we can use it as it was done now in program.cs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/0*hZZjOuflmi_l4WZI.png" /><figcaption>sample of program.cs com with dependency injection called into separate extension classes</figcaption></figure><p>All of that was replaced by a single line, referencing the method we created and taking the implementation to its original project.</p><p>Program.cs is much prettier! But the class continues with the same lines, it just changed location! Compared to some projects I’ve seen, it’s already much better, but let’s make things even simpler!</p><p>We can implement these lines in our class and solve the problem.</p><pre>var types = Assembly.GetExecutingAssembly().GetTypes()<br>    .Where(x =&gt; x.GetInterfaces().Any(i =&gt; i.Name.EndsWith(&quot;Repository&quot;)));<br><br>foreach (var type in types)<br> {<br>        var interfaces = type.GetInterfaces();<br>        foreach (var inter in interfaces)<br>            services.AddScoped(inter, type);<br> }</pre><p>But what does this code do in practice? it will scan the Assembly (compiled libraries of your project) looking for classes that are declared, and in addition, classes where their interface has the suffix “Repository”.</p><p>Note that when inspecting the “types” variable it has all the classes that were described one by one in the replaced lines of code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/0*MaK8Xg2RPRYAF683.png" /><figcaption>exemplo de dados contidos no escaneamento do assembly</figcaption></figure><p>So, the dependency injections of this project will be mapped and the problem resolved.</p><p>Within the foreach command, it will implement the classes it mapped one by one!</p><p>But…. It’s still complex, imagine in a “solution” that I have many projects, and in each project I have to replicate these lines to scan the Assembly? I will have more lines of code in some cases than going straight to the description of each class/repository!</p><p>What is the solution? create a method that does all this and I can use it throughout the solution by executing the same logic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/0*Sy5sUCJ3Z81O_qjt.png" /><figcaption>Extension method created to scan classes and interfaces in Assembly</figcaption></figure><p>So let’s create this method and use it in all other projects where I need to do dependency injection based on Interface / Class.</p><p>By creating the method above, we can eliminate all of our previous lines! Look how it turned out below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/0*MiiTRBg3EdcooQWH.png" /><figcaption>sample code using Assembly scan method</figcaption></figure><p>Now we replace all those lines with a single line, triggering the created extension method! (remember to add the usage of your namespace at the top otherwise it will not be displayed associated with a “services” method.</p><p>A very important point is that our “Assembly” is passed as a parameter within the extension method, because if the method belongs to another project (as I did here) we will not have problems not finding the classes we want, as the assembly of the extension may be another!</p><p>Okay, now you can use it in any part of your solution to solve dependency injection problems, eliminating many lines and that annoying work of looking class by class and doing everything manually.</p><p>What are the benefits of scanning the Assembly?</p><ul><li>I don’t need to insert a line to declare this dependency every time I create a class and a repository or service (in fact, who has never run the application and realized they forgot that?).</li><li>There is no need to remove a line in startup when removing a class and interface.</li></ul><p>What could go wrong?</p><p>If your application have some implementation with similar names that does not comply with the interface/class dependency, if this happens, inject the conflicting items in the previous way or change the name of the classes to avoid conflicts.</p><p>This will certainly eliminate several lines from your code and you won’t need to insert a new line for each new class created.</p><p>Did you like the article? Click the 👏 icon and follow me to see upcoming publications! If you like to see more publications see my networks into my linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=caf4c3c2942f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Resolving “Cannot load library libgssapi_krb5.so.2” in .NET 8 Linux Containers]]></title>
            <link>https://medium.com/@nizzola.dev/resolving-cannot-load-library-libgssapi-krb5-so-2-in-net-8-linux-containers-a86194ac374f?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/a86194ac374f</guid>
            <category><![CDATA[kerberos]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[entity-framework-core]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[dotnet-core]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Wed, 06 Nov 2024 00:47:38 GMT</pubDate>
            <atom:updated>2024-11-06T00:47:38.172Z</atom:updated>
            <content:encoded><![CDATA[<h3>Resolving “Cannot load library libgssapi_krb5.so.2” in .NET 8 Linux Containers</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*L3f68jxbzS9iT9iQYAxTBQ.png" /><figcaption>Resolving “Cannot load library libgssapi_krb5.so.2” in .NET 8 Linux Containers</figcaption></figure><p>When developing .NET applications in a containerized environment, you might encounter the error “Cannot load library libgssapi_krb5.so.2”. This message typically indicates an authentication issue when connecting your application to a SQL Server database.</p><p><strong>Error log in the Docker container:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*KOULDE1qgkkBP8zT44KaQQ.png" /><figcaption>Cannot load library libgssapi_krb5.so.2</figcaption></figure><p>The libgssapi_krb5.so.2 library is associated with the Kerberos protocol, a widely used authentication mechanism in enterprise networks. When you set Trusted_Connection=true in your connection string, you’re enabling Windows Integrated Authentication, which requires this library.</p><h4><strong>Why does the error occur in Linux containers?</strong></h4><p>Linux containers do not have full support for Windows Integrated Authentication. When trying to load the libgssapi_krb5.so.2 library, the operating system cannot find it, resulting in the error.</p><h4><strong>How to resolve the issue:</strong></h4><p>The simplest solution is to disable Windows Integrated Authentication by setting Trusted_Connection=false in your connection string.</p><p>With this change, your application should work as expected, provided that your connection is based on username and password and not on Windows authentication.</p><p>Did you enjoy the article? Click the 👏 icon and follow me to stay updated on upcoming publications! See my other medium profile in portuguese with +100 articles <a href="https://marcionizzola.medium.com/">https://marcionizzola.medium.com/</a>.</p><p>If you’d like to see more of my work, visit my social networks on my Linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><h4>References:</h4><p><a href="https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/8.0/krb5-libs-package">https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/8.0/krb5-libs-package</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a86194ac374f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating and Running a .NET API in Docker]]></title>
            <link>https://medium.com/@nizzola.dev/creating-and-running-a-net-api-in-docker-c92e908c845f?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/c92e908c845f</guid>
            <category><![CDATA[containerization]]></category>
            <category><![CDATA[c-sharp-programming]]></category>
            <category><![CDATA[csharp]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Sun, 15 Sep 2024 20:57:11 GMT</pubDate>
            <atom:updated>2024-09-15T20:57:11.424Z</atom:updated>
            <content:encoded><![CDATA[<h3>Creating and Running a .NET API in Docker</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*wb89Zk_J86nz5ar3Q1Ks2g.png" /><figcaption>Creating and Running a .NET API in Docker</figcaption></figure><p>In this post, I will demonstrate something quite simple that will greatly facilitate the development and testing of .NET applications on your machine.</p><p>First, let’s create an API from the .NET template as a base using the following command:</p><pre>dotnet new webapi -minimal — name DotnetApi</pre><p>Once this is done, our application is created. Let’s navigate to the folder where it’s located and run the command dotnet run.</p><p>If everything goes well, you will see this in the console:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*H6KuC6Aw8bkiQpFC.png" /></figure><p>Now, just open your browser and type <a href="https://localhost:7232/swagger">https://localhost:7232/swagger</a> to see the following result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*wp3WCBI7Gw-ouWqr.png" /></figure><p>Great! The API is now built according to the .NET template.</p><p>Our next step is to configure it to run in Docker. We’ll open VSCode and create a file in the folder, saving it as “Dockerfile” (with no extension).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/718/1*dSBO1-FMVHuQZYUYW2dAgg.png" /></figure><p>In this script, an instance of the alpine image is mounted as the base, which will serve as the final product, and another instance is used as the build environment where the application will be built.</p><p>Then, the published content (without including the source code) is copied to the base image.</p><p>Now that it’s done and the file is saved, we go back to the command line and use the following command:</p><pre>docker build . -t dotnetapi1</pre><p>This command prepares the image for our application, where dotnetapi1 is the name it will have in our local Docker repository. It runs everything defined in the Dockerfile, and now all that’s left is to execute it.</p><pre>docker run -p 8080:5000 -e ASPNETCORE_ENVIRONMENT=Development dotnetapi1 - name dotnetapi1</pre><p>By executing this command, Docker will actually run the image, generating a specific container for it, which will respond on port 8080. Additionally, I set the ASPNETCORE_ENVIRONMENT variable to “Development” because Swagger is configured by default to run only in a Development environment.</p><p>Now, just open your browser and test using localhost:8080.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*XT0WsLlWE3xr2EGt.png" /></figure><p>It works!! But what if I want to have another container running? Is that possible?</p><pre>docker run -p 8081:5000 -e ASPNETCORE_ENVIRONMENT=Development dotnetapi1 - name dotnetapi2</pre><p>The result is here: running on different ports, we have two containers of the same application!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*YEkUwnx92iVs-rPp.png" /></figure><p>If we look at the Docker interface now, we see two containers running the same application simultaneously! But how can we identify each one?</p><p>Each container in Docker is displayed with a unique identifier:</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*b31hiO4ynbDLRrXWEFF4aQ.png" /></figure><p>Let’s edit our application to retrieve the machine name where it’s running and display it in Swagger!</p><p>To do this, we’ll edit our program.cs to include the OpenApi implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*Sy_mFhxZV99KRRV6.png" /></figure><p>We need to rebuild our container by creating the image again and then running docker run once more.</p><p>As a result, we can now see that the machine name is displayed in Swagger. Additionally, we can modify our application so that the logs include the machine name to help identify the source of the logs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*oCG_lhKr9HG6TOSg.png" /></figure><p>Did you enjoy the article? Click the 👏 icon and follow me to stay updated on upcoming publications! See my other medium profile in portuguese with +100 articles <a href="https://marcionizzola.medium.com/">https://marcionizzola.medium.com/</a>.</p><p>If you’d like to see more of my work, visit my social networks on my Linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><p>Project repository: <a href="https://github.com/NIZZOLA/DotNetApiWithDocker">https://github.com/NIZZOLA/DotNetApiWithDocker</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c92e908c845f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to solve: JsonException: A possible object cycle was detected.]]></title>
            <link>https://medium.com/@nizzola.dev/how-to-solve-jsonexception-a-possible-object-cycle-was-detected-9a349439c3cd?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/9a349439c3cd</guid>
            <category><![CDATA[json]]></category>
            <category><![CDATA[exception]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[serialize-and-deserialize]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Fri, 15 Dec 2023 17:44:53 GMT</pubDate>
            <atom:updated>2025-10-31T20:09:55.178Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*bjkJJr0McxY1g0snKR0kaw.png" /><figcaption>How to solve: JsonException: A possible object cycle was detected.</figcaption></figure><p>Who has never encountered this error when returning a response from the Entity Framework directly to an API and gets this message:</p><h3>An unhandled exception occurred while processing the request.</h3><p>JsonException: A possible object cycle was detected.</p><p><em>Before start, remeber to click the 👏 icon and follow me to stay updated on upcoming publications, it´s very important !</em></p><p>This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. …..</p><p>System.Text.Json.ThrowHelper.ThrowJsonException_SerializerCycleDetected(int maxDepth).</p><p>Whenever you go through this, it is a simple and easy-to-solve problem, because when we map an object in the Entity Framework, it has references to the “parent” object in the relationship in a cyclical way, where again the “parent” will have the “ son” endlessly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/689/1*GGpziFDwF2FAbsrmgSJMHA.png" /></figure><p>This is due to the mapping of entities and normally occurs when we use the “Include” command to bring an entity that is associated with another, as below:</p><pre>var result = _context.Cliente.Include(a =&gt; a.Enderecos).ToList();</pre><p>This reminds me of a Matrioska (Russian doll that fits inside each other almost infinitely).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/810/1*A3aGkwWqFdGd8PUvFOmE5A.png" /></figure><p>We have different solutions for each case:</p><p>If you are still using Controllers and your application is above .NET 3, just put this in the initialization of your application:</p><pre>services.AddControllers().AddJsonOptions(x =&gt;<br>   x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve);</pre><p>If you are using Minimal Api, insert the code below when starting the application (program.cs).</p><pre>builder.Services.Configure&lt;Microsoft.AspNetCore.Http.Json.JsonOptions&gt;(options =&gt; options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);</pre><p>Now, if you are still mapping using Newtonsoft.Json, the solution would be like this:</p><pre>services.AddControllers().AddNewtonsoftJson(x =&gt; <br> x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);</pre><p>Did you enjoy the article? Click the 👏 icon and follow me to stay updated on upcoming publications! See my other medium profile in portuguese with +100 articles <a href="https://marcionizzola.medium.com/">https://marcionizzola.medium.com/</a>.</p><p>If you’d like to see more of my work, visit my social networks on my Linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9a349439c3cd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to use dependency injection in a Console App with .NET elegantly]]></title>
            <link>https://medium.com/@nizzola.dev/how-to-use-dependency-injection-in-a-console-app-with-net-elegantly-9e59f108bb53?source=rss-f6e24590bee6------2</link>
            <guid isPermaLink="false">https://medium.com/p/9e59f108bb53</guid>
            <category><![CDATA[dependency-injection]]></category>
            <category><![CDATA[dotnet]]></category>
            <category><![CDATA[console-app]]></category>
            <category><![CDATA[csharp]]></category>
            <dc:creator><![CDATA[Marcio Nizzola - MVP]]></dc:creator>
            <pubDate>Fri, 15 Sep 2023 10:08:38 GMT</pubDate>
            <atom:updated>2025-10-31T20:13:06.409Z</atom:updated>
            <content:encoded><![CDATA[<h3>How to use dependency injection in a Console App with .NET elegantly</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*NMDRlujxphbA-xz6yOjhgw.png" /><figcaption>How to use dependency injection in a Console App with .NET elegantly</figcaption></figure><p>Many times we need to construct console applications who need to use Dependency Injection, but console template from .NET is very simple and do not implement this by default.</p><p><em>Before start, remeber to click the 👏 icon and follow me to stay updated on upcoming publications, it´s very important !</em></p><p>Here, I will show you how to implement dependency injection elegantly using extension methods.</p><p>See this example of my “program.cs” :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/956/1*bvSlfhxMDN9D2tB5mKnP-Q.png" /><figcaption>sample of dependency injection in .net console app</figcaption></figure><p>In line 5, we have a instance of variable “environmentName” to be used to get configuration file after.</p><p>In line 7, the “configuration” variable is created to get our settings from “appsettings.json” and “appsettings” with environment name variable, like “appsettings.development.json” or “appsettings.stage.json”.</p><p>In line 13, we instantiate a variable ‘services’ with a ‘ServiceCollection’ instance. It’s used later to insert and retrieve our services via Dependency Injection.</p><p>In line 14, we call method named “ConfigureNizzolaAzure” on the “services” variable. What is that? It´s an extension method created to configure depencency injection outside “program.cs”.</p><p>The “cherry on the top” is this method; It´s an extension method who implement dependency injection in a more elegant way, as explained below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0IVKjA3dngruJdonoiJLPw.png" /></figure><p>Details:</p><ul><li>It’s a static class and method because we use the ‘this’ parameter to create an extension method for ‘IServiceCollection’. This allows your variables in ‘program.cs’ to use this method during application startup (as seen in line 7 of program.cs).</li><li>we receive “IConfigurationRoot” as a method parameter named “configuration” to be used in line 11.</li><li>in line 11, we get “section” from “appsettings” using configuration variable, and inject into “ServiceCollection”, it´s important to use “NizzolaAzureOptions” class when we need to inject into services via Dependency Injection. (as the same way of my <a href="https://medium.com/@nizzola.dev/loading-configurations-in-net-using-the-ioptions-pattern-in-a-console-app-3911cf74c449">old post</a> ).</li><li>in line 13, we prepare dependency injection of services, assign interface “INizzolaAzureBlobService” and class “NizzolaAzureBlobService”, in a singleton lifecycle.</li></ul><p>Now it´s ok, when you need to use dependency injection, in “program.cs “ you only need to get instance from “ServiceCollection”, this command in line 17 do this:</p><pre>var blobService = serviceProvider.GetService&lt;INizzolaAzureBlobService&gt;();</pre><p>Afterward, you only need to call methods on the ‘blobService’ as shown in line 21 of program.cs:</p><pre>await blobService.UploadFile(&quot;images\\8meetupItu.jpg&quot;);</pre><p>Can we improve even more? Yes, wait for the next posts to see other examples of code improvements.<br><strong><em>“Better than writing code is deleting code!” Unknown author</em></strong></p><h4>Important 👏</h4><p>Did you enjoy the article? Click the 👏 icon and follow me to stay updated on upcoming publications! If you’d like to see more of my work, visit my social networks on my Linktree: <a href="https://linktree.com/nizzola">https://linktree.com/nizzola</a></p><h4>References:</h4><ul><li><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-7.0&amp;WT.mc_id=DX-MVP-5004978">Options pattern in ASP.NET Core</a></li><li><a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection?view=dotnet-plat-ext-7.0&amp;WT.mc_id=DX-MVP-5004978">IServiceCollection Interface (Microsoft.Extensions.DependencyInjection)</a></li><li><a href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods?WT.mc_id=DX-MVP-5004978">Extension Methods - C# Programming Guide - C#</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9e59f108bb53" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>