<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tural Suleymani</title>
    <description>The latest articles on DEV Community by Tural Suleymani (@turalsuleymani).</description>
    <link>https://dev.to/turalsuleymani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1332827%2F66d3f041-ab8e-48ac-9041-f55274afaa6b.png</url>
      <title>DEV Community: Tural Suleymani</title>
      <link>https://dev.to/turalsuleymani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/turalsuleymani"/>
    <language>en</language>
    <item>
      <title>Why You Should Use Domain-Driven Design in Your Real Projects?</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Tue, 27 May 2025 09:30:09 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/why-you-should-use-domain-driven-design-in-your-real-projects-3mmp</link>
      <guid>https://dev.to/turalsuleymani/why-you-should-use-domain-driven-design-in-your-real-projects-3mmp</guid>
      <description>&lt;p&gt;In this article, I am going to talk about why you should use Domain-Driven Design (DDD) in your practice. Does it really make sense to use Domain-Driven Design in your practice? This is the most fundamental, the most important question when you start thinking about applying Domain-Driven Design.&lt;/p&gt;

&lt;p&gt;Before reading article, it is worth to check my youtube video :&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/jVRI5F7rL3I"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Well, let’s get started.&lt;/p&gt;

&lt;p&gt;The first fundamental problem is the two-language problem.&lt;/p&gt;

&lt;p&gt;We have the language of business and software development. Business people work in a problem space. They try to learn more about the business, gather more information about it, and pass this information on to software developers.&lt;/p&gt;

&lt;p&gt;Software developers, on the other hand, try to understand the business, ask more relevant questions about it, and translate the business language into software development.&lt;/p&gt;

&lt;p&gt;Business people speak in a completely different language, but you have a completely different language in your code. So we have two languages. We are working in one company, but we are speaking two different languages. This is the most fundamental problem of classical software development.&lt;/p&gt;

&lt;p&gt;When you use Domain-Driven Design, your business language becomes the language of software developers , and you don’t need any translation. You have zero translation — completely zero translation. You’re speaking the same language. We have ubiquitous language in Domain-Driven Design, which helps us speak in a single language. You have business terms, and these terms will be mapped exactly as-is to your software development. You don’t need to think about how to rename a class or how to name a method. What type of signature should it have etc.&lt;/p&gt;

&lt;p&gt;This is a big problem because you are translating the business language. But Domain-Driven Design helps you not to translate, to have zero translation, and to use the same language.&lt;/p&gt;

&lt;p&gt;Why is using the same language important?&lt;/p&gt;

&lt;p&gt;Because the business helps software developers write really good code. On the other hand, developers help the business understand the domain because we are using the same language. We are helping each other.We, as developers, help the business. The business helps developers.&lt;/p&gt;

&lt;p&gt;Another benefit is understanding the code. Even business people with limited technical knowledge can easily understand your code and easily identify where to make changes. As a software developer, it won’t take you a long time to add features or make changes to your code because you already know where to make the updates.&lt;/p&gt;

&lt;p&gt;Understanding the code is really important — even for new engineers.&lt;/p&gt;

&lt;p&gt;Let’s say in our company, we hire a new software developer. I don’t need to explain everything related to the code or the business or provide a lot of documentation, because our code is our documentation.&lt;/p&gt;

&lt;p&gt;If you understand our code, you already understand our documentation. You understand our business. Because business is code. Design is code. Code is design.&lt;/p&gt;

&lt;p&gt;Domain-Driven Design also helps us centralize business knowledge.&lt;/p&gt;

&lt;p&gt;The business helps developers write good code. Developers ask a lot of detailed questions about the business. And the business also learns more about the business — because business people don’t know everything either.&lt;/p&gt;

&lt;p&gt;We, as developers, help the business to learn more about the business. And in the end, both developers and business people gain deep knowledge about the business.&lt;/p&gt;

&lt;p&gt;This is really important because knowing the business will help you write even better, more understandable, and more readable code.&lt;/p&gt;

&lt;p&gt;On the other hand, Domain-Driven Design is an agile, iterative process. In modern software development, it is really important to have an iterative approach. DDD is a 100% iterative process.&lt;/p&gt;

&lt;p&gt;And the last benefit for me is, of course, having a toolbox or toolset for development.&lt;/p&gt;

&lt;p&gt;We have cool design patterns — strategic patterns, tactical patterns — you can apply. You can use ubiquitous language, bounded context, context mapping, entities, value objects, aggregates, domain events, domain services, modules, repositories, and more as design patterns when using Domain-Driven Design.&lt;/p&gt;

&lt;p&gt;So for me, you should apply Domain-Driven Design when you have a complex business domain — like a banking domain or an insurance domain. Please don’t use Domain-Driven Design for technical complexities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Domain-Driven Design (DDD) is not just a technical framework — it’s a strategic approach to building software that mirrors the business it serves. By eliminating the communication gap between business experts and developers, DDD enables teams to speak the same language, build systems that reflect the domain accurately, and iterate efficiently. Whether you’re building complex domains like banking or insurance, DDD equips you with the right mindset and a powerful set of tools to create scalable, understandable, and maintainable software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔑 Key Takeaways from the article&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1.The Two-Language Problem&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional development suffers from a disconnect between business language and software code.&lt;/li&gt;
&lt;li&gt;DDD bridges this gap by unifying both into a shared language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;2.Ubiquitous Language&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everyone (business and developers) speaks the same language.&lt;/li&gt;
&lt;li&gt;Reduces confusion and eliminates the need for translation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;3. Improved Code Understanding&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Even non-technical business people can read and understand the code.&lt;/li&gt;
&lt;li&gt;New developers need less onboarding because the code is self-explanatory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;4. Code as Documentation&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code itself acts as living documentation of the business rules and structure.&lt;/li&gt;
&lt;li&gt;Reduces the need for redundant external documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;5. Mutual Growth and Collaboration&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;_Developers help the business refine their domain knowledge.&lt;/li&gt;
&lt;li&gt;Business helps developers write better, domain-aligned code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;6. Centralized Business Knowledge&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The domain model becomes the single source of truth.&lt;/li&gt;
&lt;li&gt;Both technical and non-technical teams gain deep insights into the business.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;7. Iterative and Agile-Friendly&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DDD naturally supports agile and iterative development.&lt;/li&gt;
&lt;li&gt;Makes it easier to adapt to evolving business needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;8. Rich Toolbox for Modeling&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DDD offers powerful design patterns:&lt;/li&gt;
&lt;li&gt;Strategic: Bounded Contexts, Context Mapping&lt;/li&gt;
&lt;li&gt;Tactical: Entities, Value Objects, Aggregates, Domain Events, Services, Repositories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;9. Suitable for Complex Domains&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best applied in domains with inherent business complexity (e.g., banking, insurance).&lt;/li&gt;
&lt;li&gt;Should not be used for purely technical complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to dive deeper?&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;TuralSuleymaniTech(English version) &lt;/a&gt;YouTube channel, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>domaindrivendesign</category>
      <category>whyddd</category>
      <category>turalsuleymani</category>
    </item>
    <item>
      <title>NoSQL vs. SQL: Which One to Use</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Sun, 04 May 2025 17:52:17 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/nosql-vs-sql-which-one-to-use-5epn</link>
      <guid>https://dev.to/turalsuleymani/nosql-vs-sql-which-one-to-use-5epn</guid>
      <description>&lt;p&gt;If you’ve participated in many interviews, you’ve probably heard the question: “What are the differences between NoSQL and SQL databases?” This article will help you clearly understand these differences and when to choose one over the other.&lt;/p&gt;

&lt;p&gt;As a software developer, you may have already worked with various SQL databases such as T-SQL, PostgreSQL, MySQL, and others. What’s the first thing you’ve likely noticed? The “rules” or the “schema,” of course. SQL databases have highly structured data models. You create tables with defined columns and rows, strictly following a predetermined schema. Breaking this structure means violating the fundamental principles of SQL. Tables, columns, rows, and data types form the essential building blocks for organizing your data.&lt;/p&gt;

&lt;p&gt;On the other hand, when you work with NoSQL databases (non-relational databases) like Azure Cosmos DB, Aurora, or MongoDB, you have the flexibility to frequently modify your data model. NoSQL databases don’t enforce a rigid structure. They provide an “elastic” schema, allowing you to store data in various formats. Instead of sticking to the traditional table representation, you can use document-based, key-value-based, graph-based, or column-based models, among others.&lt;/p&gt;

&lt;p&gt;For relational databases, developers usually apply normalization (such as first normal form, second normal form, etc.) to ensure a clear and balanced data structure. As a result, relational databases often rely heavily on multi-table JOINs, aggregations, and complex relationships to retrieve data. However, when datasets become large, it can be challenging and inefficient to manage and retrieve data quickly from relational databases.&lt;/p&gt;

&lt;p&gt;Unfortunately, relational databases aren’t inherently designed to handle massive volumes of data. They follow a “scale-up” approach, meaning they require more resources such as RAM, CPU, and GPU to handle increased data.&lt;/p&gt;

&lt;p&gt;NoSQL databases, however, are designed for “scaling out.” This means you can distribute and handle data across multiple servers without negatively impacting performance. Many people associate “NoSQL” with “Big Data,” often using these terms interchangeably. Indeed, you can consider the term “NoSQL” a buzzword frequently associated with solving big data challenges.&lt;/p&gt;

&lt;p&gt;Behind NoSQL Lies the 3V Principle&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Volume&lt;/li&gt;
&lt;li&gt;Velocity&lt;/li&gt;
&lt;li&gt;Variety&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1l7mcbxdnfqgq1ooac8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1l7mcbxdnfqgq1ooac8.png" alt="3v principle" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s examine each of these elements individually to understand their importance.&lt;/p&gt;

&lt;p&gt;Volume refers to handling massive datasets, reaching terabytes, petabytes, and beyond. Thanks to the “scale-out” design, NoSQL databases comfortably manage vast amounts of data without issues. SQL databases, by comparison, often struggle with such extensive data sets due to limitations in hardware scaling and structured data constraints, making them less efficient for extremely large data scenarios.&lt;/p&gt;

&lt;p&gt;Velocity is about throughput — handling massive amounts of simultaneous requests quickly and efficiently. NoSQL databases excel at processing high-velocity data streams, which is crucial for applications like social media feeds, real-time analytics, IoT applications, and more. SQL databases may experience bottlenecks due to their rigid schemas and transaction overhead, slowing down performance in high-throughput situations.&lt;/p&gt;

&lt;p&gt;Variety emphasizes schema flexibility. You can utilize any of the schema forms mentioned previously or even choose a schema-less approach entirely. This schema flexibility means NoSQL databases can easily accommodate rapidly evolving data requirements, different data formats, and unstructured or semi-structured data like images, videos, and sensor data. Conversely, SQL databases are best suited for structured and consistent data that doesn’t frequently change.&lt;/p&gt;

&lt;p&gt;Let’s explore more internal details between them.&lt;/p&gt;

&lt;p&gt;**1. Transactions and ACID Compliance: **SQL databases generally offer strong consistency and ACID (Atomicity, Consistency, Isolation, Durability) compliance. NoSQL databases often sacrifice strict ACID compliance for scalability and flexibility, adopting eventual consistency models.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Complex Queries and Reporting: SQL databases excel in executing complex queries, and multi-table joins, and providing extensive reporting capabilities. NoSQL databases might require additional processing layers or specialized query mechanisms for complex analytical queries.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;3. Scaling Approaches:&lt;/strong&gt; SQL databases typically scale vertically (adding more resources to a single server), while NoSQL databases scale horizontally (adding more servers), providing more flexibility and efficiency for handling large datasets.&lt;/p&gt;

&lt;p&gt;Understanding these differences and key characteristics will help you choose the right database solution based on your specific requirements. The best measure for your application is your context. The application context defines which one is perfect for you.&lt;/p&gt;

&lt;p&gt;Want to dive deeper?&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;TuralSuleymaniTech(English version)&lt;/a&gt; YouTube channels breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
      <category>nosql</category>
      <category>sql</category>
      <category>volume</category>
      <category>velocity</category>
    </item>
    <item>
      <title>The best way of implementing Domain-driven design, Clean Architecture, and CQRS</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Sat, 28 Dec 2024 13:39:58 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/the-best-way-of-implementing-domain-driven-design-clean-architecture-and-cqrs-124p</link>
      <guid>https://dev.to/turalsuleymani/the-best-way-of-implementing-domain-driven-design-clean-architecture-and-cqrs-124p</guid>
      <description>&lt;p&gt;Today, I am going to show you the best way learning Domain-Driven Design, Clean Architecture, CQRS, and Software Design Principles in practice. As you might know, there are many interesting books out there that help us gain valuable information about Domain-Driven Design, Clean Architecture, CQRS, and other topics. But nowadays, most developers don’t have enough time to read books or may not want to spend time reading books. Of course, I don’t admire this approach, but it is what it is. And in the era of AI, we want to learn everything fast. That’s why I think using tutorials and real-world examples from GitHub or other sources will help you reach your destination.&lt;/p&gt;

&lt;p&gt;For that reason, I’m going to show you one of &lt;a href="https://github.com/TuralSuleymani/the-real-DDD-CQRS-CleanArchitecture" rel="noopener noreferrer"&gt;the best domain-driven design, CQRS, a clean architecture repository&lt;/a&gt;. And I hope you will like this repository. I have provided almost all possible best ways of implementing domain-driven design and clean architecture in this repo. You can just check the readme file &lt;a href="https://github.com/TuralSuleymani/the-real-DDD-CQRS-CleanArchitecture" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvimm8vj12hbljpcczjh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvimm8vj12hbljpcczjh3.png" alt="clean architecture, domain-driven design, cqrs" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t like huge articles, jusat check my video where I explained this article’s content in more detail:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/TjoNaJ7n4Vg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Of course, in GitHub, you may find a lot of interesting repositories which demonstrate Domain-driven design, clean architecture, CQRS, and other stuff. But fortunately, most of them are just garbage for me because they don’t demonstrate real-world examples, they are just pet projects.&lt;/p&gt;

&lt;p&gt;But for me, the best way of implementing domain-driven design, is clean architecture should look like this. And that’s why I implemented this repository. So here we have a lot of interesting features.&lt;/p&gt;

&lt;p&gt;✨ Features&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Basket Management:&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create baskets with basket items.&lt;/li&gt;
&lt;li&gt;Underlying architecture for Add, update, and remove items.&lt;/li&gt;
&lt;li&gt;Underlying architecture for Calculate total amounts including tax and shipping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Coupon System:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Underlying architecture for Apply and remove discount coupons.&lt;/li&gt;
&lt;li&gt;Underlying architecture for Support for fixed and percentage-based discounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Clean Architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separation of concerns with clearly defined layers.&lt;/li&gt;
&lt;li&gt;Independent and replaceable infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Domain-Driven Design:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on business rules encapsulated in the domain layer.&lt;/li&gt;
&lt;li&gt;Events for tracking domain state changes.&lt;/li&gt;
&lt;li&gt;Tactical and Strategical DDD patterns: Ubiquitous Language,Bounded Context,Value Objects, Entities, Aggregates, Domain Events, Domain Services, Application services, Repositories, Factories,Modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cross-Cutting Concerns:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logging: Centralized and consistent logging for debugging and monitoring.&lt;/li&gt;
&lt;li&gt;Validation: Reusable validation logic using FluentValidation to ensure data integrity.&lt;/li&gt;
&lt;li&gt;Exception Handling: Unique exception handling to provide meaningful error messages and prevent crashes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3aboccuqxoblqg3n1kj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3aboccuqxoblqg3n1kj.png" alt="domain-driven design behaviours" width="318" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I tried to implement almost all possible patterns from domain-driven design like &lt;em&gt;ubiquitous language, bounded context, value objects, entities, aggregates, domain events, domain services, application services, repositories, factories, modules, and more&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The development process in our case starts from Event Storming.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepzq5dgbrq7cbhu06q06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepzq5dgbrq7cbhu06q06.png" alt="event storming" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the details of the source code, please check the Event Storming Board. It will help you to understand why we implemented such type of features and Event Storming will help you to understand the core ubiquitous language used in our application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TuralSuleymani/the-real-DDD-CQRS-CleanArchitecture" rel="noopener noreferrer"&gt;Our Application&lt;/a&gt; was implemented using clean architecture and I applied best practices to demonstrate the usage of clean architecture in rich business applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f6lwjxhrphercg34o0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f6lwjxhrphercg34o0i.png" alt="clean architecture high-level design" width="800" height="363"&gt;&lt;/a&gt;&lt;br&gt;
Here is the simple explanation for the diagram:&lt;/p&gt;

&lt;p&gt;First, we have a user. User sends request to the web API. We have the application layer which handles the API query using CQRS and it forwards, it acts like orchestrator between domain models. And we have domain models that we are retrieving, we are manipulating and domain models raises &lt;strong&gt;domain events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5xktsagqun2tiyhufku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5xktsagqun2tiyhufku.png" alt="domain-driven design diagram" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These events will be caught by the event dispatcher. And for the event dispatching, we have events and event handlers. Our events will be caught by event handlers. And if you want to go outside of your bounded context, we have integration events that will help you to publish you event outside. For example, in our context, we have Apache Kafka implementation. You can push your event to the outside using Apache Kafka.&lt;/p&gt;

&lt;p&gt;So as you see, we have approximately more than 10 Domain-Driven Design patterns here, but that’s not all. Of course, I have used other Design patterns, let’s say from the GoF Patterns. For example, we have the Greg Young’s CQRS here.&lt;/p&gt;

&lt;p&gt;We have the &lt;a href="https://youtu.be/Pq4XLWxt-T8" rel="noopener noreferrer"&gt;Result pattern&lt;/a&gt; from the functional programming. We have a decorator, mediator, publisher-subscriber, strategy, template method, factory method, chain of responsibility, unit of work, and more. If you really want to see all these patterns in practice in real-world examples, this repository is one of the best to investigate and learn all these concepts using only one project.&lt;/p&gt;

&lt;p&gt;So now let’s dive into the details of this project using Visual Studio. In our application, you might guess, we have two main folders. They are source(&lt;strong&gt;src&lt;/strong&gt;) folder and &lt;strong&gt;tests&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F311sq64a7fn1hw5lpw97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F311sq64a7fn1hw5lpw97.png" alt="domain-driven design folder structure" width="231" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our &lt;strong&gt;source&lt;/strong&gt; folder, we have &lt;strong&gt;clean architecture&lt;/strong&gt; and the shared library functionality. And in &lt;strong&gt;tests&lt;/strong&gt; folder, we have unit tests plus the test data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrx3mbt51a9v0u4bs8po.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrx3mbt51a9v0u4bs8po.png" alt="clean architecture implementation" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, I have just implemented unit testing here and I will add integration tests, but for now, I approximately implemented all possible unit test scenarios for this project. Let’s start from the source(src) folder. You should first try to understand the domain layer here.&lt;/p&gt;

&lt;p&gt;In our domain design applications, you are implementing microservices using a domain-driven design. In this approach, you know, we have special naming rule. In our case, we have VOEConsulting.Flame.BasketContext.Domain. ‘VOE consulting’ is a company name. ‘Flame’ is the application name. ‘BasketContext’ is a bounded context name and the ‘Domain’ is the layer name.&lt;/p&gt;

&lt;p&gt;Lets start from the domain layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93ujyjyladlr1go76v5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93ujyjyladlr1go76v5y.png" alt="domain-driven design domain layer" width="312" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have &lt;strong&gt;Basket&lt;/strong&gt;, &lt;strong&gt;Coupon&lt;/strong&gt; and we have &lt;strong&gt;Common&lt;/strong&gt; folders. In our basket, you will find all the entities, aggregates, value objects, events, and services related to the basket. And the same is applicable for the Coupon also. After reviewing our event storming, you will understand why we have basket and coupon implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public sealed class Basket : AggregateRoot&amp;lt;Basket&amp;gt;
{
    public IDictionary&amp;lt;Seller, (IList&amp;lt;BasketItem&amp;gt; Items, decimal ShippingAmountLeft)&amp;gt; BasketItems { get; private set; }
    public decimal TaxPercentage { get; }
    public decimal TotalAmount { get; private set; }
    public Customer Customer { get; private set; }
    public Id&amp;lt;Coupon&amp;gt;? CouponId { get; private set; } = null;

    private Basket(decimal taxPercentage, Customer customer)
    {
        BasketItems = new Dictionary&amp;lt;Seller, (IList&amp;lt;BasketItem&amp;gt;, decimal)&amp;gt;();
        TaxPercentage = taxPercentage.EnsurePositive();
        TotalAmount = 0;
        Customer = customer;
    }

    public void AddItem(BasketItem basketItem)
    {
        if (BasketItems.TryGetValue(basketItem.Seller, out (IList&amp;lt;BasketItem&amp;gt; Items, decimal ShippingAmountLeft) value))
        {
            value.Items.Add(basketItem);
        }
        else
        {
            BasketItems.Add(basketItem.Seller, (new List&amp;lt;BasketItem&amp;gt; { basketItem }, basketItem.Seller.ShippingLimit));
        }

        RaiseDomainEvent(new BasketItemAddedEvent(this.Id, basketItem));
    }

    public static Basket Create(decimal taxPercentage, Customer customer)
    {
        var basket = new Basket(taxPercentage, customer);
        //basket.RaiseDomainEvent(new BasketCreatedEvent(basket.Id, customer.Id));
        return basket;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have implemented approximately all possible domain-driven design, strategical, and tactical patterns. For example, our Basket is an Aggregate Root. Our Coupon is an Aggregate Root also. Aggregate root is a type of entity that has possibilities related to events. You can add events, clear events, pop events ,and more.&lt;/p&gt;

&lt;p&gt;Just go to the definition. I have implemented approximately all the base classes using by myself. I haven’t used any libraries here. So you see we have aggregate root, it is inherited from the entity and it has this sort of functionalities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public abstract class AggregateRoot&amp;lt;TModel&amp;gt; : Entity&amp;lt;TModel&amp;gt;, IAggregateRoot
    where TModel : IAuditableEntity
{
    private readonly IList&amp;lt;IDomainEvent&amp;gt; _domainEvents = new List&amp;lt;IDomainEvent&amp;gt;();
    public IReadOnlyCollection&amp;lt;IDomainEvent&amp;gt; DomainEvents =&amp;gt; _domainEvents.AsReadOnly();

    public IReadOnlyCollection&amp;lt;IDomainEvent&amp;gt; PopDomainEvents()
    {
        var events = _domainEvents.ToList();
        ClearEvents();
        return events;
    }

    public void ClearEvents()
    {
        _domainEvents.Clear();
    }

    protected void RaiseDomainEvent(IDomainEvent domainEvent)
    {
        domainEvent.EnsureNonNull();
        _domainEvents.Add(domainEvent);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The best way of exploring &lt;a href="https://github.com/TuralSuleymani/the-real-DDD-CQRS-CleanArchitecture" rel="noopener noreferrer"&gt;this repository&lt;/a&gt; is you don’t need to implement everything from scratch. I will have series of tutorials which help you to understand this project in more detail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgmabyx521sql3dd95mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgmabyx521sql3dd95mr.png" alt="domain-driven design domain layer visualization" width="273" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just an overview of the application which help you to understand the high level implementation of domain driven design, clean architecture, CQRS and the software development best practices. So just go to VOEConsulting.Flame.Common.Domain. And here we have all sorts of contracts, abstract classes for our application.&lt;/p&gt;

&lt;p&gt;All sorts of aggregates inherited from Aggregate Root. If you have entity, your entity should inherit from the abstract entity class. If you have value object, your value object should inherit from the abstract value object class. Also, I have mentioned that if you want to use records, there is no need to implement such type of class because the records will handle all the equality component functionality.&lt;/p&gt;

&lt;p&gt;In our domain layer, I’m throwing exceptions, but catching these sort of mechanisms using result pattern in a domain layer is also completely okay. I mean, you don’t need to throw exceptions. You can just easily wrap them to the result pattern and send it to the application layer. This is also completely okay, but I have used the exception-throwing mechanism here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnp6b3u0o2ouf8ylfq9tv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnp6b3u0o2ouf8ylfq9tv.png" alt="domain-driven design domain layer validation" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We validate entities, aggregates, and value object through these extension methods. For example, in our basket, we have, for example, ensure positive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private Basket(decimal taxPercentage, Customer customer)
{
    BasketItems = new Dictionary&amp;lt;Seller, (IList&amp;lt;BasketItem&amp;gt;, decimal)&amp;gt;();
    TaxPercentage = taxPercentage.EnsurePositive();
    TotalAmount = 0;
    Customer = customer;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure positive is a checking mechanism will help us to check if the given value is positive or not. So I have approximately all sorts of extension methods for all sorts of scenarios, but in the future, I may add or remove some of them.&lt;/p&gt;

&lt;p&gt;Long story short, in our VOEConsulting.Flame.BasketContext.Domain, we have domain oriented logic,on the other hand, in VOEConsulting.Flame.Common.Domain we have shared domain layer features.&lt;/p&gt;

&lt;p&gt;I will create a separate NuGet package that will help you to just easily install and use these features. But right now, you can just by yourself create your own private NuGet repository and use it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb7qkxd5rqq6j604ne3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb7qkxd5rqq6j604ne3e.png" alt="clean architecture" width="386" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next layer in our application is going to be our &lt;strong&gt;Application Layer&lt;/strong&gt;. The responsibility of our application layer is to handle commands and queries using CQRS. In our Web API, we have request mechanism and we are requesting some data and we are forwarding it to our application layer using CQRS.As you might guess, I have future based mechanism and it looks like a &lt;strong&gt;vertical slice architecture&lt;/strong&gt;. For instance, we have create basket functionality. It has Command, Command handler and validator; like all in one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1bpwl9bdnkuduogxy9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1bpwl9bdnkuduogxy9b.png" alt="clean architecture application layer" width="345" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The command handling mechanism is really easy because we have &lt;a href="https://github.com/TuralSuleymani/the-real-DDD-CQRS-CleanArchitecture/blob/main/src/VOEConsulting.Flame.BasketContext.Application/Abstractions/CommandHandlerBase.cs" rel="noopener noreferrer"&gt;common handler base&lt;/a&gt;, which we have wrapped all the repeated steps into one abstract class and using template method pattern. You can just inherit and rewrite the exact **ExecuteAsync **method. So every time when we are handling a request, we have a special core handling mechanism.&lt;/p&gt;

&lt;p&gt;I don’t have any validation code here because I have cross-cutting concerns in our behaviors on the application. So you see we have exception handling pipeline behavior and this pipeline behavior will help you to handle the exception stuff. And we have logging and we have validation.&lt;/p&gt;

&lt;p&gt;We have a domain model orchestration like aggregate/entity orchestration in our application layer.&lt;/p&gt;

&lt;p&gt;Of course, the domain layer throws exceptions, but I mentioned, exception handling pipeline behavior will catch it and will provide the value for you result.&lt;/p&gt;

&lt;p&gt;The domain events will help us to notify the changes about our aggregate inside our bounded context. But if you want to go outside of our bounded context, you should map it to the integrated event and raise the integrated event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public sealed class BasketCreatedIntegrationEvent : IntegrationEvent
{
    public BasketCreatedIntegrationEvent(Id&amp;lt;Basket&amp;gt; basketId, Guid customerId)
        : base(basketId)
    {
        CustomerId = customerId;
    }

    public BasketCreatedIntegrationEvent() { }

    public Guid CustomerId { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have orchestration mechanism because in one domain model you are storing a part of business related to use case in another domain model you are storing another part of business so we need to orchestrate them to get one use case that’s why we are using application layer and it is responsible for publishing our domain events and of course.&lt;/p&gt;

&lt;p&gt;So integration events will be handled in our infrastructure layer because we are going outside of our bounded context. For example, we need to publish an event to message queue and we will implement the exact implementation of message queue in our infrastructure layer. And we have repository interfaces. Why I haven’t put these interfaces to domain layer because I don’t think that it is the best way of implementing repository interfaces in our case. Why? Because in my domain layer, I’m not using these interfaces. This is a bit design decision. If you have the exact implementation for your interfaces, if you are actually using these interfaces in the domain layer, you should put them to domain layer. If you are not using them in your domain layer, it would be better to move them to the upper layer like the application layer. In my case, I put them into our application layer.&lt;/p&gt;

&lt;p&gt;Now lets talk about our infrastructure layer. The responsibility of infrastructure is to work with outside elements. If you have mail sending, you have working with GraphQL, Apache Kafka, external services, databases, you should put all these mechanisms’ implementation inside your infrastructure. For example, I have put my interfaces to the application layer, but this interfaces implementation will be stored in our infrastructure layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33qat9tpv0fhy87d099v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33qat9tpv0fhy87d099v.png" alt="clean architecture infrastructure layer" width="320" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So,as you see, I have persistence, have all sort of entity framework configurations, I have all sort of entities here, profiles for mapping and the exact unit of work implementation. I have DB context here. I have all sorts of repository implementations.&lt;/p&gt;

&lt;p&gt;In our infrastructure, we are handling all the exact implementations related to the outside world.&lt;/p&gt;

&lt;p&gt;And the higher one is our API layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyra11ogzng2uhodbz1a7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyra11ogzng2uhodbz1a7.png" alt="clean architecture api layer" width="312" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have simple **BasketController **here. The responsibility of basket controller is actually getting the request data from the user and forward it to the lower layers. In my case, for example, we have create basket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ApiController]
[Route("api/[controller]")]
public class BasketController(ISender sender, ILogger&amp;lt;BasketController&amp;gt; logger) : BaseController(logger)
{
    private readonly ISender _sender = sender;

    // GET api/basket/{id}
    [HttpGet("{id}")]
    public async Task&amp;lt;IActionResult&amp;gt; GetBasket(Guid id)
    {
        var result = await _sender.Send(new GetBasketQuery(id));
        return result.IsSuccess ? Ok(result) : HandleError(result.Error);
    }

    // POST api/basket
    [HttpPost]
    public async Task&amp;lt;IActionResult&amp;gt; CreateBasket([FromBody] CreateBasketCommand command)
    {
        var result = await _sender.Send(command);
        if (result.IsSuccess)
            return CreatedAtAction(nameof(GetBasket), new { id = result.Value }, result.Value);
        return HandleError(result.Error);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;basket creation is a command, not a query. That’s why we have a create basket command. Using ISender’s send, we are forwarding it to the application layer, actually. And the combination of application + infrastructure will handle all this stuff for us. I have implemented base controller that will help us easily work with controllers. I don’t have too much logic because you should not put logic to your API layer if they are not related to the API layer. For example, if I need to wrap some data from the lower layer to the bad request ,I don’t now, to the 404, 400, 500, of course, I should interact with API layer. Otherwise, you should not add any logic to this API layer. So just check this controller. I will add more features. Of course, we haven’t implemented all possible endpoints for basket, for coupon, but I will add them one by one. This application will help you to understand domain driven design, clean architecture, and of the best way of implementing software. And of course, we have tests. How it is possible to write application without tests. I have almost implemented&lt;/p&gt;

&lt;p&gt;all possible best ways of using unit tests in this application. Starting from the next tutorials, I will create a series of articles to explain almost all possible parts of this application. I will start from the unit tests and using these implementations, you can easily understand and adapt it to your current projects.&lt;/p&gt;

&lt;p&gt;So that’s what I have implemented and I hope you will love this repository. Just go to &lt;a href="https://github.com/TuralSuleymani" rel="noopener noreferrer"&gt;Tural Suleymani’s GitHub&lt;/a&gt; and in my git, you will find the real domain-driven design, CQRS and clean architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🌟 If you find &lt;a href="https://github.com/TuralSuleymani/the-real-DDD-CQRS-CleanArchitecture" rel="noopener noreferrer"&gt;this repository&lt;/a&gt; helpful or interesting, please don’t forget to give it a star! It really helps and motivates me to keep improving and sharing more projects. Thank you! 🌟&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;See you in our next tutorials, bye.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to dive deeper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech/videos" rel="noopener noreferrer"&gt;TuralSuleymaniTech &lt;/a&gt;youtube channel, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
      <category>domaindrivendesign</category>
      <category>cqrs</category>
      <category>tutorial</category>
      <category>cleanarchitecture</category>
    </item>
    <item>
      <title>I’m Preparing for FAANG : Getting Started with Essentials</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Thu, 26 Dec 2024 19:27:21 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/im-preparing-for-faang-getting-started-with-essentials-2f4n</link>
      <guid>https://dev.to/turalsuleymani/im-preparing-for-faang-getting-started-with-essentials-2f4n</guid>
      <description>&lt;p&gt;Data structures and algorithms are important, but it is not always easy to grasp their main ideas. This “I’m Preparing for FAANG “series will help you not just learn data structures and algorithms but also dive into their philosophy. The final purpose of this series is to help you achieve your goal: To pass FAANG interviews.&lt;/p&gt;

&lt;p&gt;This is the first and most foundational lesson from the series. In this tutorial, you’ll understand what exactly a data structure is and how we interact with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting started with Data structures&lt;/strong&gt;&lt;br&gt;
Data structure is simply a way of structuring data. What does it mean? It means they are essentially how data is stored, retrieved, and organized.&lt;/p&gt;

&lt;p&gt;Data is always important. In software development, we usually work with different data structures, and using different algorithms, we interact with this data. Whether it is a small application like a utility tool, a huge web application that serves billions of people, or a machine learning model, the manipulation and management of data is a crucial process of our system.&lt;/p&gt;

&lt;p&gt;The purpose of interacting with data defines its structure. You may need the fastest way of getting data, or you don’t care about retrieving it, but your focus is on storing the data/ writing the data.&lt;/p&gt;

&lt;p&gt;When you first learn data structures, you may come up with a foundational question: Why do we have so many data structures out there?&lt;/p&gt;

&lt;p&gt;Well, the choice of a data structure depends heavily on how the data will be used. So, The actual reason is your business/requirements. Consider the following cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you need the fastest way of retrieving data, you can pick tables or arrays&lt;/li&gt;
&lt;li&gt;If your main focus is storing the data, linked lists or compressed tries may be a relevant choice for you&lt;/li&gt;
&lt;li&gt;If you need to maintain the order, data structures like binary search trees or sorted arrays are often used.&lt;/li&gt;
&lt;li&gt;If your data grows unpredictably, you may pick dynamic arrays or linked lists.
As you might guess, the requirement for the data structure is the main case here. That is why we have a lot of data structures, and that is why you should deal with so many data structures throughout your learning and working process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Getting started with Algorithms&lt;/strong&gt;&lt;br&gt;
Data structures alone are not sufficient. What is the purpose of picking up the most suitable data structure if you don’t have a way of interacting with it? Well. That is why we need algorithms to interact with this data effectively.&lt;/p&gt;

&lt;p&gt;We encapsulate the following logic inside our algorithms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How quickly can new data be inserted into the structure? For example, inserting data into an array is faster than inserting it into a sorted linked list.&lt;/li&gt;
&lt;li&gt;Can we remove elements efficiently?&lt;/li&gt;
&lt;li&gt;How about sorting and searching? Algorithms like binary search, merge sort, and quicksort are important when it comes to large datasets.&lt;/li&gt;
&lt;li&gt;How fast can we access the element? Searching for an element in a table is faster than a sequential search through an array.
&lt;strong&gt;Random Access memory&lt;/strong&gt;
We mostly structure data inside a RAM. RAM stands for Random Access Memory. The performance of our application heavily depends on how well the data structure is utilized by RAM. There is no single way of interacting with RAM when it comes to data structure and RAM communication. Almost every data structure interacts with RAM in a unique way that affects performance, memory usage, and system efficiency.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We temporarily store data and instructions inside RAM for quick access to the CPU.&lt;/p&gt;

&lt;p&gt;Data structures stored in RAM are accessed faster compared to other storage like hard drives, etc. So, RAM’s speed and organization directly affect how effectively data structures perform operations like read, search, delete, etc.&lt;/p&gt;

&lt;p&gt;As you already know, RAM is measured in bytes (e.g. 16 GB RAM or 32 GB RAM), which represents the total amount of data it can hold at once.&lt;/p&gt;

&lt;p&gt;All data in RAM, whether text, numbers, or instructions, is stored in binary format. For example, the symbol “A” ( in ASCII) is stored as 01000001 (1 byte). Each byte in RAM is associated with a unique memory address. In the end, the CPU uses these addresses to locate and interact with the data stored there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdv5f90l3x25rgcdehfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdv5f90l3x25rgcdehfe.png" alt="tural in RAM" width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our next tutorial, we will talk about arrays, but let’s focus on storing the name ‘Tural’ in RAM. When it comes to storing the ASCII symbols, we all know that every ASCII symbol is 1 byte. Almost in all programming languages, when you specify a string, it acts like an array of chars, so they are the contiguous block of information. In RAM, the system will represent it sequentially. Every symbol of the string is one byte, so the next address in RAM will be increased to 1.&lt;/p&gt;

&lt;p&gt;But byte is not the smallest representation of data. Originally, RAM stored a combination of 0 and 1, which we call binary representation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzj6khmefjfaohdy7d6re.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzj6khmefjfaohdy7d6re.png" alt="ASCII description" width="800" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After getting the binary representation, let’s see how it will be displayed in RAM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbw5xykgo7fzvtidg3kw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbw5xykgo7fzvtidg3kw.png" alt="data in RAM" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh, yes, I forgot to mention, that preparing for FAANG doesn’t start from the exact questions, it starts from the foundations. When you move forward, you will understand that the fundamentals are the most important ones. Well, let’s wrap up what we have learned so far:&lt;/p&gt;

&lt;p&gt;A bit is the smallest unit of data, and a byte is a combination of 8 bits. RAM is a temporary data storage where we store our arrays, linked lists, hash tables, and other data structures. Efficient use of RAM is crucial for optimized data handling.&lt;/p&gt;

&lt;p&gt;Don’t worry. We will learn all these data structures in more detail.&lt;/p&gt;

&lt;p&gt;Data, such as the name “Tural” is represented in memory as binary sequences. In ASCII, every symbol is 1 byte, so the name “Tural” will be 5 bytes. In total, we have 8*5=40 bits for this name.&lt;/p&gt;

&lt;p&gt;Understanding binary representation in most cases helps to optimize our software design, whether working with low-level memory or preparing for interviews with FAANG companies.&lt;/p&gt;

&lt;p&gt;See you in our next lessons. If you like my content, you can follow me on &lt;a href="https://www.linkedin.com/in/tural-suleymani/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to dive deeper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech/videos" rel="noopener noreferrer"&gt;TuralSuleymaniTech&lt;/a&gt; YouTube channels, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us!&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>datastructures</category>
      <category>tutorial</category>
      <category>faang</category>
    </item>
    <item>
      <title>The Cynefin framework with Domain-driven Design</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Mon, 25 Nov 2024 17:26:57 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/the-cynefin-framework-with-domain-driven-design-4g2p</link>
      <guid>https://dev.to/turalsuleymani/the-cynefin-framework-with-domain-driven-design-4g2p</guid>
      <description>&lt;p&gt;I first met the term ‘Cynefin’ when learning Domain-driven Design. I have seen multiple mentions of this framework, but not all of them were related to software development, especially DDD. The thing here is that the Cynefin framework is not directly related to the software industry. It is more than that. In simple terms, the Cynefin framework, developed by Dave Snowden back in 1999, is a decision-making and sense-making tool designed to help leaders and organizations deal with complex problems and make better decisions.&lt;/p&gt;

&lt;p&gt;I know you may have tried to learn it before this article, and because of its complexity and complex explanations, you may fail. This article aims to try to explain it as simply as possible.&lt;/p&gt;

&lt;p&gt;If you learn DDD, you may notice that understanding the domain is important and trying to understand how complex the domain is really complex.&lt;/p&gt;

&lt;p&gt;Cynefin framework and domain-driven design(DDD) address complexity, deal with complex systems, and aim to provide frameworks for managing uncertainty. Cynefin categorizes problems to determine how to address them. On the other hand, DDD focuses on managing complexity in business domains by modeling them effectively.&lt;/p&gt;

&lt;p&gt;Using Cynefin, we can identify which domain(s) in a system are Complex or Complicated, influencing how DDD might be applied.&lt;/p&gt;

&lt;p&gt;Cynefin’s primary purpose is to guide decision-makers in understanding the context of a situation and applying appropriate strategies.&lt;/p&gt;

&lt;p&gt;So far, so good. Now, we have some basic understanding of the Cynefin framework, and it is time to dive into the five realms of the framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2sm7gep3wp6f2c9l817.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2sm7gep3wp6f2c9l817.png" alt="cynefin framework" width="413" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Cynefin framework categorizes problems into five domains, each representing a different type of system or context. It doesn’t matter if you’re a developer, manager, or a non-IT guy, throughout the working process you always deal with some problems. While the Cynefin framework helps categorize problems and provides general guidance on how to approach them, it does not describe the exact “steps of operations” to deal with issues. Instead, it offers principles or strategies adapted to the characteristics of each domain. You should remember that Cynefin is about adapting strategies to fix the context, not about following strict, predefined steps. While a “step-by-step” procedure might work in the Clear domain of Cynefin, in the Chaotic domain, quick action to stabilize the situation is prioritized.&lt;/p&gt;

&lt;p&gt;The first domain in Cynefin is the &lt;strong&gt;Clear/Obvious/Simple domain&lt;/strong&gt;. This domain typically deals with well-defined, predictable problems where ”best practices” are sufficient. In contrast, DDD is designed for complex and complicated domains, where understanding and modeling the domain requires collaboration, expertise, and iterative refinement. The main approach in this domain is “sense-categorize-respond”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: Before categorizing the problem, we observe and recognize the situation to identify the problem. In the Clear domain, the situation is easily understandable because it fits into established patterns or rules. You don’t need to apply deep analysis or experimentation. These sorts of problems don’t even require a domain expert. A simple example may be an email validation. We observe that the system needs to validate an email address provided by a user. The problem is really simple: ensure the email format meets a standard pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Categorize&lt;/strong&gt;: We have a category of “solutions” here, and we match the observed situation to a known category or pattern. We choose the corresponding best practice or standard procedure to address the issue. In terms of email validation, this problem is a well-understood problem and has established patterns and best practices. We need to categorize the issue as “input validation using predefined standard” and apply a regular expression or use a library function for validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt;: Based on categorization, we need to implement the pre-defined solution. There is no need for innovative thinking- just follow the existing rules or steps. In terms of email validation, use the best practice for email validation(Simple domain). Implement a regex or library-based validator in the code and provide feedback to the user if the email doesn’t match the expected format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Text.RegularExpressions;class Program
{
    static void Main()
    {
        Console.WriteLine("Enter an email address:");
        string email = Console.ReadLine();if (IsValidEmail(email))
        {
            Console.WriteLine("The email is valid.");
        }
        else
        {
            Console.WriteLine("The email is invalid.");
        }
    }

    static bool IsValidEmail(string email)
    {
        if (string.IsNullOrWhiteSpace(email))
        {
            return false;
        }
        // Simple email validation regex
        string emailPattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";
        return Regex.IsMatch(email, emailPattern);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A real-world example of a clear-domain problem involving a car wash where the water supply runs out might look like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: Recognize the problem: The car wash system detects that the water supply has been depleted (e.g., through a water level sensor or manual observation). The cause is obvious and easily identifiable: there is no water left to continue operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : The water tank for the car wash is empty, and the system cannot proceed with washing cars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Categorize&lt;/strong&gt;: Match the situation to a known category: Categorize the problem as “resource depletion.”&lt;/p&gt;

&lt;p&gt;Determine the standard operating procedure (SOP) for refilling the water tank. This is a routine task with established steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : Check the water tank level. Confirm it needs refilling. Identify the nearest water source or supplier for replenishment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt;: Apply the known solution: Follow the established procedure to resolve the problem. Notify the operator to refill the tank or automatically trigger the water refilling mechanism if the system is automated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; : Refill the water tank from the designated source. Ensure the tank is full. Resume car wash operations once the water is replenished.&lt;/p&gt;

&lt;p&gt;The next domain is the &lt;strong&gt;Complicated domain&lt;/strong&gt;. The main approach here is “sense-analyze-respond”. A complicated domain represents situations where problems are more challenging than in the Clear domain, but they are still solvable with expertise and analysis. The cause-and-effect relationships exist, but they are not immediately obvious and require deeper investigation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Any characteristics of the Complicated Domain?&lt;/em&gt; Of course:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We don’t have best practices. Instead of this, we have multiple solutions -&amp;gt; good practices.&lt;/li&gt;
&lt;li&gt;It requires expertise and specialists.&lt;/li&gt;
&lt;li&gt;The system is stable enough to allow analysis, but understanding it requires more effort than simple categorization.&lt;/li&gt;
&lt;li&gt;The Recommended Approach for Complicated domains is Sense-Analyze-Respond.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: Gather data and observe the situation to identify the problem.&lt;br&gt;
&lt;strong&gt;Analyze&lt;/strong&gt;: Use expertise, tools, or frameworks to investigate the cause-and-effect relationships. Explore different options and evaluate their potential outcomes.&lt;br&gt;
&lt;strong&gt;Respond&lt;/strong&gt;: Implement the solution deemed most effective based on the analysis.&lt;br&gt;
In terms of the car domain, say we need to design a car’s engine. To build a car engine, we need expertise in engineering, as there are many variables to consider, like fuel efficiency, durability, emissions, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Differences between domains:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62nrmybbtwm5gssqeos2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62nrmybbtwm5gssqeos2.png" alt="cynefin framework domain differences" width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In terms of DDD, we can/should apply DDD for such types of problems. A complicated domain requires expert input to understand and analyze problems when DDD centers on domain experts collaborating with developers to create models that accurately represent the business domain. Long story short, the relationship between the Complicated domain and DDD lies in their shared focus on dealing with complex problem-solving scenarios.The both:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Emphasize the need for expert input.&lt;/li&gt;
&lt;li&gt;In the complicated domain, good practices guide decision-making, and solutions are not obvious but discoverable. By its nature, DDD introduces structured methodologies to tackle complexity.&lt;/li&gt;
&lt;li&gt;The iterative analysis in the complicated domain aligns well with DDD’s emphasis on continuously evolving the domain model.&lt;/li&gt;
&lt;li&gt;In a complicated domain, experts might segment the problem into understandable parts to apply solutions effectively. Similarly, DDD introduces bounded contexts to isolate complexities within specific subdomains.
As an example, the tax domain can be a complicated domain example in C#. Besides the language, we need to understand the tax domain. It means you need to involve someone from this domain to understand and solve the problem:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
class Program
{
    static void Main()
    {
        Console.WriteLine("Enter your income:");
        decimal income = decimal.Parse(Console.ReadLine());
        Console.WriteLine("Enter the number of dependents:");
        int dependents = int.Parse(Console.ReadLine());
        Console.WriteLine("Are you self-employed? (yes/no):");
        bool isSelfEmployed = Console.ReadLine()?.Trim().ToLower() == "yes";
        var taxCalculator = new TaxCalculator();
        decimal tax = taxCalculator.CalculateTax(income, dependents, isSelfEmployed);
        Console.WriteLine($"Your calculated tax is: {tax:C}");
    }
}
public class TaxCalculator
{
    private readonly List&amp;lt;ITaxRule&amp;gt; _taxRules;
    public TaxCalculator()
    {
        _taxRules = new List&amp;lt;ITaxRule&amp;gt;
        {
            new BasicIncomeTaxRule(),
            new DependentDeductionRule(),
            new SelfEmploymentTaxRule()
        };
    }
    public decimal CalculateTax(decimal income, int dependents, bool isSelfEmployed)
    {
        decimal tax = 0;
        foreach (var rule in _taxRules)
        {
            tax += rule.Apply(income, dependents, isSelfEmployed);
        }
        return Math.Max(tax, 0); // Ensure tax is not negative
    }
}
public interface ITaxRule
{
    decimal Apply(decimal income, int dependents, bool isSelfEmployed);
}
public class BasicIncomeTaxRule : ITaxRule
{
    public decimal Apply(decimal income, int dependents, bool isSelfEmployed)
    {
        // Example: Flat 20% tax for incomes above 50,000
        if (income &amp;gt; 50_000)
        {
            return (income - 50_000) * 0.20M;
        }
        return 0;
    }
}
public class DependentDeductionRule : ITaxRule
{
    public decimal Apply(decimal income, int dependents, bool isSelfEmployed)
    {
        // Example: $2,000 deduction per dependent
        return -dependents * 2000;
    }
}
public class SelfEmploymentTaxRule : ITaxRule
{
    public decimal Apply(decimal income, int dependents, bool isSelfEmployed)
    {
        if (isSelfEmployed)
        {
            // Example: 15% self-employment tax on all income
            return income * 0.15M;
        }
        return 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The third domain is the** Complex domain.** The complex domain involves systems where the cause-and-effect relationship can only be understood in retrospect. Solutions arise through experimentation, probing, and feedback loops. There are no best and good practices. You must experiment with small changes to understand how the system behaves and adapt accordingly. Collaboration is very important in identifying emerging patterns. The main approach here is “probe-sense-respond”. Because relationships between actions and outcomes are not directly observable or predictable. The solution evolves over time through experimentation and feedback. The other important fact is: that complex domains often require inputs from multiple disciplines to approach solutions. You must be careful because a small change in one part of the system can lead to significant or unpredictable effects elsewhere.&lt;/p&gt;

&lt;p&gt;Long story short, here is the most understandable approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduce small, safe-to-fail experiments to observe how the system behaves.&lt;/li&gt;
&lt;li&gt;Observe and analyze the outcomes of the experiments.&lt;/li&gt;
&lt;li&gt;Adapt and take action based on what you’ve learned from probing and sensing.
If you think about complexity in DDD, it addresses it through Bounded contexts, clearly defined Ubiquitous language inside the context, and applying tactical design inside bounded context. Breaking the domain into Bounded Contexts helps teams focus on smaller, more manageable areas, enabling gradual understanding and refinement. DDD does not assume that all requirements or domain insights can be known upfront, making it a natural fit for complex systems. In the end, DDD enables teams to build systems that adapt and thrive in unpredictable environments.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2r93r7i50sgmrx5olgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2r93r7i50sgmrx5olgg.png" alt="clear differences in cynefin framework" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The chaos domain&lt;/strong&gt; in the Cynefin Framework represents situations where cause-and-effect relationships are completely unclear and immediate. Decisive action is required to stabilize the system. Unlike other domains, the chaotic domain is marked by extreme unpredictability and the need for rapid response to avoid further damage. Our main approach is “act-sense-respond”. It’s impossible to identify a pattern or determine how actions influence outcomes.&lt;/p&gt;

&lt;p&gt;There’s no time for analysis or experimentation; No way to apply DDD. Quick action is necessary to bring the situation under control.&lt;/p&gt;

&lt;p&gt;Our main purpose is to move the situation into a more manageable domain (e.g., complex or complicated). Without decisive action, the situation may spiral out of control.&lt;/p&gt;

&lt;p&gt;While DDD is not inherently designed for chaotic environments, aspects of its principles can help navigate and transition chaos into manageable domains.&lt;/p&gt;

&lt;p&gt;While DDD typically operates in complex and complicated domains, its principles can indirectly support efforts to manage and recover from chaos:&lt;/p&gt;

&lt;p&gt;In chaotic situations, maintaining focus on a system’s Core Domain is critical. DDD emphasizes prioritizing the core business logic, ensuring that during a chaotic event, resources and actions target the most business-critical systems or processes.&lt;/p&gt;

&lt;p&gt;Bounded Contexts help isolate parts of a system. In chaos, this separation enables teams to address and stabilize affected areas without disrupting unrelated parts.&lt;/p&gt;

&lt;p&gt;Chaos often leads to miscommunication under pressure. DDD’s emphasis on a Ubiquitous Language fosters clear communication among developers, domain experts, and other stakeholders, ensuring alignment during chaotic responses.&lt;/p&gt;

&lt;p&gt;DDD mostly applies event-driven architecture, which supports handling chaos. Systems designed with event sourcing and CQRS can respond to unexpected situations more flexibly. Also, DDD principles can guide the transition from chaos to the complex domain, where experimentation and adaptive solutions are possible. In the end, After an initial stabilization of chaotic failures, teams can use DDD techniques like Event Storming to model and understand emergent patterns, enabling iterative improvement.&lt;/p&gt;

&lt;p&gt;**The disorder domain **in the Cynefin framework represents situations where it’s unclear which of the other four domains applies. This domain is marked by confusion and lack of clarity.&lt;/p&gt;

&lt;p&gt;When the domain is poorly understood, and there is no agreement on the business goals or technical approach, you may end up with a disordered domain in the context of DDD. Well, then, how can DDD help in the disorder domain?&lt;/p&gt;

&lt;p&gt;The disorder domain then arises from miscommunication and inconsistent terminology. UL will guide you in fixing this problem. Also, trying to solve too many problems at once or overlapping responsibilities can be a good “reason” to be in the disorder domain. From the DDD perspective, splitting the domain into well-defined Bounded Contexts can help us to move from disorder to other domains.&lt;/p&gt;

&lt;p&gt;The other reason for being in the disorder domain is the lack of clarity on which parts of the domain are most important. In the context of DDD, strategic design helps identify core domains to prioritize and focus efforts where they bring the most value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
The Cynefin Framework and Domain-Driven Design (DDD) complement each other by providing a structured way to navigate complexity in software systems and business domains. While Cynefin offers a lens to categorize problems and determine suitable decision-making approaches, DDD provides concrete practices for solving problems in complicated and complex domains. Together, they form a powerful toolkit for building robust, adaptable, and business-aligned software systems.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>SQL Server Execution Plans</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Wed, 13 Nov 2024 18:52:04 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/sql-server-execution-plans-n0j</link>
      <guid>https://dev.to/turalsuleymani/sql-server-execution-plans-n0j</guid>
      <description>&lt;p&gt;There are some questions that those who are familiar with the T-SQL dialect of SQL ask themselves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why is my query working slowly?&lt;/li&gt;
&lt;li&gt;Does the query I wrote use an index?&lt;/li&gt;
&lt;li&gt;Why is the index I created not used?&lt;/li&gt;
&lt;li&gt;Why is this query slower (faster) than the other one, despite returning the same result?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want answers to these questions, one of the tools that must be used to understand them is Execution plans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is an Execution Plan?&lt;/strong&gt;&lt;br&gt;
EThe executionPlan is a description of the most efficient execution of the query we wrote, calculated by the optimizer. That is, Execution Plan shows us in which version your query is implemented, and using which algorithm it is executed.&lt;/p&gt;

&lt;p&gt;In short, how SQL Server will or has executed our query.&lt;/p&gt;

&lt;p&gt;Let's look at everything from the beginning,&lt;/p&gt;

&lt;p&gt;After we write a query, the execution of the request goes through several stages. Those stages are concentrated into 2 large groups:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Events in relation engine (RE)&lt;/li&gt;
&lt;li&gt;Events in Storage Engine (SE)
In the &lt;strong&gt;RE(relation engine)&lt;/strong&gt;, the query is parsed and executed by the query optimizer. The query optimizer prepares an execution plan. This Execution Plan is then sent in binary format to the SE(storage engine), which uses this plan during the execution of queries. Transaction and index operations are realized in the storage engine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's first open SQL SERVER and let such a request be executed. (Queries will be applied to the &lt;strong&gt;AdventureWorks2012&lt;/strong&gt; database)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use AdventureWorks2012
GO
SELECT
         hremphist.businessentityid
       , person.person.firstname
       , person.person.lastname
       , humanresources.employee.jobtitle
       , humanresources.department.name AS DepartmentName
       , hremphist.startdate
FROM (
                 SELECT
                         businessentityid
                       , departmentid
                       , startdate
                       , ROW_NUMBER() OVER (PARTITION BY businessentityid ORDER BY startdate DESC) AS rn
                 FROM humanresources.employeedepartmenthistory
         ) AS hremphist
         JOIN humanresources.department
                 ON humanresources.department.departmentid = hremphist.departmentid
         JOIN humanresources.employee
                 ON humanresources.employee.businessentityid = hremphist.businessentityid
         JOIN person.person
                 ON person.businessentityid = hremphist.businessentityid
WHERE hremphist.rn = 1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the Execution Plan of the query by pressing &lt;strong&gt;Ctrl+L&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's see together what execution processes the above request goes through,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Query Parsing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As soon as we execute the query we wrote, it is taken by &lt;strong&gt;RE&lt;/strong&gt; and checked whether it is true or false from the syntactic side (&lt;strong&gt;Parsing&lt;/strong&gt;). If there are no syntactic problems, the query has been successfully parsed. It should be remembered that if the query is DDL, it is not optimized! Because CREATE TABLE, which is a DDL operation of the example, has only one syntax. Only DML operations can be optimized. The result of the query parsing process gives us a parse tree (sequence tree, query tree).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Algebrizer&lt;/strong&gt;&lt;br&gt;
If the DML request has passed the parsing process successfully, it is sent to Algebrizer, a special mechanism. Algebrizer performs logical processes such as the existence of objects used by us, the names of table columns, compatibility of types, etc. As a result of these processes, Algebrizer returns us a binary format. Returns a "query processor tree", which results are processed by the query optimizer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Query Optimizer prepares Execution Plan for us.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) Storage Engine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Physical processing of the request is performed at this stage, and the request is executed based on the Execution Plan.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;SQL Query Optimizer&lt;/strong&gt; performs the generation and preparation of Execution Plans. When preparing an Execution Plan, it necessarily refers to statistics and indexes and uses the information collected there by the execution plan maker. In the next step, the Execution Plan given by the Query Optimizer is sent to the storage engine; based on this, our query is physically executed. It should be remembered that when an Execution Plan is prepared, the prepared plan is added to the cache (processor cache) so that it is stored in the memory. During the next similar Execution Plan preparation, the Optimizer does not have to do additional work and can use the previously generated plan.&lt;/p&gt;

&lt;p&gt;Depending on the complexity of the query, T-SQL QUERY OPTIMIZER generates several Execution Plans for us and tries to choose the fastest one among them. However, it is necessary to consider that there are often queries for which Execution Plans can be generated for their implementation, which may take several minutes. Therefore, Query Optimizer makes the necessary selection among the first generated plan combinations, not all. Gave us the perfect Execution Plan. Our EPs will be stored in the plan cache not to generate a plan for similar questions every time.&lt;/p&gt;

&lt;p&gt;To delete cached data, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DBCC FREEPROCCACHE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also delete the required plan by passing sql_handle and plan_handle specifically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What can cause the current Execution Plan to change?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Execution of parallel queries&lt;/li&gt;
&lt;li&gt;The statistics had changed or became outdated when the Execution Plan was made.&lt;/li&gt;
&lt;li&gt;Entering information into the temporary table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It should be remembered that there are 2 main forms of EP(Execution Plan) in T-SQL,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The estimated Execution Plan (Estimated execution plan) is the plan the SQL Optimizer estimates before the query is executed.&lt;/li&gt;
&lt;li&gt;Actual Execution Plan (Real execution plan) – is a plan received only after the request is released for execution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although these plans store a completely different set of data, they do not differ from each other at first glance.&lt;/p&gt;

&lt;p&gt;There are 3 main forms of execution plans,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Graphical description (Graphical plans)&lt;/li&gt;
&lt;li&gt;Description in text format (Text Plans)&lt;/li&gt;
&lt;li&gt;In XML format (XML Plans)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most commonly used representation form of execution plans is a &lt;strong&gt;Graphical plan&lt;/strong&gt;. Although the graphic description form does not reflect all the details at first glance, detailed information can be seen in the outer panel.&lt;/p&gt;

&lt;p&gt;Although &lt;strong&gt;Text Plans&lt;/strong&gt; have been declared "deprecated" by SQL Server, we can still use them. In the Text version, you can get detailed information about the plan the first time, speed it up, and edit it in a text editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET SHOWPLAN_ALL ON;
GO
SELECT TOP 100 [BusinessEntityID]
      ,[NationalIDNumber]
      ,[LoginID]
      ,[OrganizationNode]
      ,[OrganizationLevel]
      ,[JobTitle]
      ,[BirthDate]
      ,[MaritalStatus]
      ,[Gender]
      ,[HireDate]
      ,[SalariedFlag]
      ,[VacationHours]
      ,[SickLeaveHours]
      ,[CurrentFlag]
      ,[rowguid]
      ,[ModifiedDate]
FROM [ADV_Works].[HumanResources].[Employee]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the test code example above, we enabled the detailed description of the "estimated" plan in text form. To disable this mode, write OFF instead oExecutionrun the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET SHOWPLAN_TEXT ON;--active
GO
SET SHOWPLAN_TEXT OFF;--deactive
GO
SET STATISTICS PROFILE ON;--active text mode for actual plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feku98zpq98jfhiz04kbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feku98zpq98jfhiz04kbc.png" alt="plan execution" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;XML Plans - XML plans have 2 forms of description:&lt;/p&gt;

&lt;p&gt;SHOWPLAN_XML-is generated until execution&lt;br&gt;
STATISTICS_XML is generated after query execution&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkb48rwtgcv3rv7o61ohf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkb48rwtgcv3rv7o61ohf.png" alt="xml plan" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most used form of EPs is a graphical form (Graphical Execution plans).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ctrl+M (for Actual) Ctrl+L (for Estimated)&lt;/li&gt;
&lt;li&gt;By selecting the "Include Actual Execute plan" or "Display Estimated Execute Plan" button on the toolbar&lt;/li&gt;
&lt;li&gt;By right-clicking on the session, we wrote the query and selected "Include Actual Execution Plan" or "Display Estimated Execute plan" from the drop-down menu.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Want to dive deeper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;TuralSuleymaniTech(English version)&lt;/a&gt; and &lt;a href="https://www.youtube.com/@TuralSuleymaniTechRU" rel="noopener noreferrer"&gt;TuralSuleymaniTechRu (Russian version)&lt;/a&gt; YouTube channels, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>tutorial</category>
      <category>executionplan</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>Understanding API Gateways in Microservices</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Fri, 01 Nov 2024 08:22:16 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/understanding-api-gateways-in-microservices-3bha</link>
      <guid>https://dev.to/turalsuleymani/understanding-api-gateways-in-microservices-3bha</guid>
      <description>&lt;p&gt;In Microservice development, we mainly use interesting techniques and patterns. One of the interesting patterns in the microservice environment is called API Gateway. It describes a pattern for managing client requests for multiple services and offers a structured solution to various challenges in distributed systems and service-oriented architectures.&lt;/p&gt;

&lt;p&gt;This article will help you understand the real value of an API gateway and will describe how to implement a simple API gateway in practice.&lt;/p&gt;

&lt;p&gt;I always prefer to explain things in detail, let’s say in theory, before implementing it in practice. The case here is that if you don’t have theoretical fundamental knowledge or an understanding of the thing, it doesn’t make too much sense to code it, and it is mostly not possible to get the most out of the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s first answer the question: Why API Gateway?
&lt;/h2&gt;

&lt;p&gt;In your microservice environment, the natural microservice-oriented design ends up with multiple microservices where all these services are separated and have their address to reach out to and invoke them. Using API Gateway, you don’t need to remember their address. API gateway acts as a Single Entry Point for such types of services. Instead of managing multiple endpoints for different services, our clients can now connect to one endpoint( to our API gateway), and it means we don’t need to keep track of multiple services’ addresses.&lt;/p&gt;

&lt;p&gt;API Gateway service is a great place to implement our &lt;strong&gt;authentication, authorization, and SSL termination&lt;/strong&gt;. Instead of implementing all these stuff for different services, now we can write them and manage them from one single point. As you might guess, API Gateway is a fundamental place to implement other cross-cutting concerns as well.&lt;/p&gt;

&lt;p&gt;Can I implement &lt;strong&gt;logging&lt;/strong&gt; in my API gateway? Of Course, it is a good design decision to implement one of the popular cross-cutting concerns called logging here. API Gateways can log requests and provide insights into usage patterns, performance, and errors. We can use this data not just for monitoring but also for improving our services.&lt;/p&gt;

&lt;p&gt;When you have API Gateway, you can get responses from multiple services and &lt;strong&gt;aggregate them&lt;/strong&gt; to provide only one single response to the client&lt;/p&gt;

&lt;p&gt;You can implement &lt;strong&gt;data transformation&lt;/strong&gt; inside your API Gateway. Data transformation logic here will act as an architectural decorator over you services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load balancing&lt;/strong&gt; is another interesting functionality that you can integrate into your API gateway. Via Load Balancing, API gateways can distribute requests across multiple instances of a service, providing load balancing and improving systems’ scalability and resilience.&lt;/p&gt;

&lt;p&gt;What if I want to add &lt;strong&gt;some limitations for calling the exact services&lt;/strong&gt;? Well, that is also another interesting feature we implement inside the API gateway, and it is called &lt;strong&gt;Rate Limiting&lt;/strong&gt;. Gateways can limit the number of requests from a client within a specific time frame. This prevents abuse and helps maintain performance levels.&lt;/p&gt;

&lt;p&gt;Another must-have behavior for API Gateway is &lt;strong&gt;Fault tolerance&lt;/strong&gt;. In our API Gateways, we can implement &lt;strong&gt;retries, circuit breaking, and timeouts&lt;/strong&gt;. If a service is down or slow, the gateway can provide fallback mechanisms, improving overall resilience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpd0md8w3teak3td49v28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpd0md8w3teak3td49v28.png" alt="api gateway in microservices" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A small note:&lt;/em&gt; Although effective, the API Gateway pattern can introduce some overhead, such as an extra hop in communication and potential performance bottlenecks if not scaled properly. In simpler systems, a &lt;strong&gt;Backend-for-Frontend (BFF) pattern&lt;/strong&gt; is sometimes preferred, where each client type has a dedicated gateway, reducing complexity for specific use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br&gt;
As a pattern, the API Gateway provides a standardized way to handle client requests and manage cross-cutting concerns in a distributed system. It is a highly effective design pattern for microservices and complex applications that need centralized control and routing for multiple backend services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to dive deeper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;TuralSuleymaniTech(English version)&lt;/a&gt; and &lt;a href="https://www.youtube.com/@TuralSuleymaniTechRU" rel="noopener noreferrer"&gt;TuralSuleymaniTechRu (Russian version) YouTube&lt;/a&gt; channels, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Real-World Expression Trees: Dynamic Filtering in C# with Minimal API</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Tue, 22 Oct 2024 19:05:29 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/real-world-expression-trees-dynamic-filtering-in-c-with-minimal-api-2fdk</link>
      <guid>https://dev.to/turalsuleymani/real-world-expression-trees-dynamic-filtering-in-c-with-minimal-api-2fdk</guid>
      <description>&lt;p&gt;In our previous tutorial, we discussed key points of expression trees, use cases, and limitations. Any topic without a practical example, especially if it is related to programming, doesn’t make much sense. This article will discuss the second part of expression trees in C# and demonstrate the real power of using Expression trees in practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we’re going to build?&lt;/strong&gt;&lt;br&gt;
Our main purpose is to build an Asp.NET Core web API with dynamic filtering functionality built with minimal API, EF core, and, of course, Expression Trees.&lt;/p&gt;

&lt;p&gt;We plan to build filtering over the product database and use Expression trees to show one of the real powers of expression trees when it comes to building complex and dynamic queries.&lt;/p&gt;

&lt;p&gt;PS: If reading is boring then you can watch the complete tutorial here where I explain everything from scratch, one by one:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/lkZxn76w88U"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;For the Russian version of the video use the following link:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5oiAk1lK340"&gt;
&lt;/iframe&gt;
&lt;br&gt;
Here is the final example with multiple dynamic filtering arguments:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90todh0h9tfqov3tp05h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90todh0h9tfqov3tp05h.gif" alt="expression trees in practice" width="706" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a more complete example, please refer to &lt;a href="https://github.com/TuralSuleymani/DecodeBytes/tree/tutorial/expression-trees-in-practice" rel="noopener noreferrer"&gt;the GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting started&lt;/strong&gt;&lt;br&gt;
First, open Visual Studio and select the Asp.NET Core Web API template with the following configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpl8vfu1qdmww804wevol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpl8vfu1qdmww804wevol.png" alt="configuration in vs" width="597" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use .NET 8.0, but the topic itself doesn’t depend on any .NET version. You can even use classical .NET Framework to use Expression Trees. The project name is “ExpressionTreesInPractice”.&lt;/p&gt;

&lt;p&gt;Here is the generated template from the Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbuzeipjzqttdhxu0j98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbuzeipjzqttdhxu0j98.png" alt="visual studio template" width="264" height="150"&gt;&lt;/a&gt;&lt;br&gt;
To have simple storage, we will use InMemory Ef Core. You can use any other EF Core sub-storage.&lt;/p&gt;

&lt;p&gt;Now go to &lt;strong&gt;Tool-&amp;gt;Nuget Package Manager-&amp;gt;Package Manager Console&lt;/strong&gt; and type the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;install-package microsoft.entityframeworkcore.inmemory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s create our DbContext implementation. Create a folder called ‘Database’ and add a class called ProductDbContext to it with the following implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using ExpressionTreesInPractice.Models;
using Microsoft.EntityFrameworkCore;

namespace ExpressionTreesInPractice.Database
{
    public class ProductDbContext : DbContext
    {
        public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
        public ProductDbContext(DbContextOptions&amp;lt;ProductDbContext&amp;gt; options) : base(options) { }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity&amp;lt;Product&amp;gt;().HasData(new List&amp;lt;Product&amp;gt;
            {
                new Product(){ Id = 1, Category = "TV", IsActive = true, Name = "LG", Price = 500},
                new Product(){ Id = 2, Category = "Mobile", IsActive = false, Name = "Iphone", Price = 4500},
                new Product(){ Id = 3, Category = "TV", IsActive = true, Name = "Samsung", Price = 2500}
            });
            base.OnModelCreating(modelBuilder);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just need some basic initialized data when we run our application, and that is why we need to override OnModelCreating from DbContext. A great example of a template method pattern, isn’t it?&lt;/p&gt;

&lt;p&gt;We need our Entity model called &lt;strong&gt;Product&lt;/strong&gt;, and you can create a folder called ‘&lt;strong&gt;Models&lt;/strong&gt;’ and add the Product class to it with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace ExpressionTreesInPractice.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
        public bool IsActive { get; set; }
        public string Name { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is time to register our DbContext implementation in the Program.cs file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;builder.Services.AddDbContext&amp;lt;ProductDbContext&amp;gt;(x =&amp;gt; x.UseInMemoryDatabase("ProductDb"));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By the way, Program.cs has tons of unnecessary code snippets that we need to remove. After the cleaning process, our should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using ExpressionTreesInPractice.Database;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddDbContext&amp;lt;ProductDbContext&amp;gt;(x =&amp;gt; x.UseInMemoryDatabase("ProductDb"));

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseHttpsRedirection();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don’t want to use controllers because they are heavy and cause additional problems. That is why we choose to use minimal API. If you don’t know what minimal API is, please refer to our &lt;strong&gt;video tutorial&lt;/strong&gt; to learn more.&lt;/p&gt;

&lt;p&gt;After understanding it, open Program.cs and add the following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.MapGet("/products", async ([FromBody] ProductSearchCriteria productSearch, ProductDbContext dbContext) =&amp;gt; { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code defines a route in a minimal ASP.NET Core API and creates an endpoint for an HTTP GET request to the &lt;strong&gt;/products&lt;/strong&gt; path. The method uses asynchronous programming to handle potentially long-running operations without blocking the main application flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ProductSearchCriteria&lt;/strong&gt; is a parameter passed to the method, which contains the criteria used to filter the products. It's marked with [FromBody], meaning the request body will be bound to this parameter. Usually, GET requests don't use request bodies, but this setup is allowed if you need to pass a complex object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ProductDbContext&lt;/strong&gt; is the database context, which represents the session with the database. It's injected into the method, allowing the application to perform operations like querying the database for products based on the search criteria.&lt;/p&gt;

&lt;p&gt;The reason for using &lt;code&gt;**ProductSearchCriteria**&lt;/code&gt; instead of &lt;code&gt;**Product**&lt;/code&gt; is that the query needs to be dynamic. In this case, the user may provide some of the attributes of the &lt;code&gt;**Product**&lt;/code&gt;, but not all of them. Since the properties of &lt;code&gt;**Product**&lt;/code&gt; are not nullable, the user would be required to provide every property, even if they don't want to filter by all of them.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;**ProductSearchCriteria**&lt;/code&gt;, we allow for more flexibility. It acts as a container for optional and dynamic parameters. The user can choose to provide only the attributes they want to search by, making it a better fit for scenarios where not all product properties are needed in the query.&lt;/p&gt;

&lt;p&gt;Here is what our &lt;strong&gt;ProductSearchCriteria&lt;/strong&gt; class looks like in the ‘Models’ folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace ExpressionTreesInPractice.Models
{
    public record PriceRange(decimal? Min, decimal? Max);
    public record Category(string Name);
    public record ProductName(string Name);
    public class ProductSearchCriteria
    {
        public bool? IsActive { get; set; }
        public PriceRange? Price { get; set; }
        public Category[]? Categories { get; set; }
        public ProductName[]? Names { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's focus on our minimal API implementation. Please take into account that the purpose of the current tutorial is not to show the best practices or write clean code. The purpose is to demonstrate Expression trees in practice and after learning the point you can easily refactor the code.&lt;/p&gt;

&lt;p&gt;Here is our first code snippet inside the **MapGet **function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await dbContext.Database.EnsureCreatedAsync();

 ParameterExpression parameterExp = Expression.Parameter(typeof(Product), "x");

 Expression predicate = Expression.Constant(true);//x=&amp;gt;True &amp;amp;&amp;amp; x.IsActive=true/false


 if (productSearch.IsActive.HasValue)

 {

     MemberExpression memberExp = Expression.Property(parameterExp, nameof(Product.IsActive));

     ConstantExpression constantExp = Expression.Constant(productSearch.IsActive.Value);

     BinaryExpression binaryExp = Expression.Equal(memberExp, constantExp);

     predicate = Expression.AndAlso(predicate, binaryExp);

 }

var lambdaExp = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(predicate, parameterExp);

var data = await dbContext.Products.Where(lambdaExp).ToListAsync();

 return Results.Ok(data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is using C#'s Expression classes to dynamically build a predicate for querying a database. Let's break it down step by step.&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;await dbContext.Database.EnsureCreatedAsync();&lt;/strong&gt;&lt;br&gt;
This line asynchronously ensures that the database is created. If it doesn’t exist, it will be created. This is typically used in development or testing environments to ensure the database schema is in place.&lt;br&gt;
2.&lt;strong&gt;ParameterExpression parameterExp = Expression.Parameter(typeof(Product), "x");&lt;/strong&gt;&lt;br&gt;
Here, a parameter expression is created to represent an instance of the Product class. This will act as the input parameter (x) in the expression tree, similar to how you define a lambda expression like x =&amp;gt; ....&lt;br&gt;
3.&lt;strong&gt;Expression predicate = Expression.Constant(true);&lt;/strong&gt;&lt;br&gt;
An initial predicate is created as a constant boolean expression with the value true. This is useful for building the dynamic predicate incrementally, as you can use it as a base to add more conditions (e.g., true AND other conditions). It serves as a starting point for combining additional expressions.&lt;br&gt;
4.&lt;strong&gt;if (productSearch.IsActive.HasValue)&lt;/strong&gt;&lt;br&gt;
This block checks if the IsActive property in productSearch is not null, meaning the user has provided a filter for whether the product is active or not.&lt;br&gt;
5.Inside the if block:&lt;br&gt;
&lt;strong&gt;MemberExpression memberExp = Expression.Property(parameterExp, nameof(Product.IsActive));&lt;/strong&gt;&lt;br&gt;
This creates a &lt;strong&gt;MemberExpression *&lt;em&gt;that accesses the IsActive property of the Product instance represented by parameterExp (x.IsActive). Essentially, it represents the expression x =&amp;gt; x.IsActive.&lt;br&gt;
**ConstantExpression constantExp = *&lt;/em&gt;&lt;/strong&gt;Expression.Constant(productSearch.IsActive.Value);**&lt;br&gt;
A ConstantExpression is created with the value of productSearch.IsActive. This represents the value to compare against (true or false).&lt;br&gt;
&lt;strong&gt;BinaryExpression binaryExp = Expression.Equal(memberExp, constantExp);&lt;/strong&gt;&lt;br&gt;
A BinaryExpression is created to compare the IsActive property with the provided value. This represents x.IsActive == productSearch.IsActive.&lt;br&gt;
&lt;strong&gt;predicate = Expression.AndAlso(predicate, binaryExp);&lt;/strong&gt;&lt;br&gt;
The current predicate (which started as true) is combined with the new condition (x.IsActive == productSearch.IsActive) using a logical AND. This results in an expression that can be used to filter products based on their active status.&lt;/p&gt;

&lt;p&gt;Overall, the above code is dynamically building an expression tree that will eventually be used to filter products based on whether they are active. The initial predicate (true) allows for additional conditions to be added easily without special handling for the first condition. If productSearch.IsActive is provided. It adds a condition that checks if the product’s IsActive property matches the given value (true or false).&lt;/p&gt;

&lt;p&gt;Then, the lambdaExp variable is assigned a lambda expression that represents a filtering function for the Product entities. This lambda expression is created from the predicate built earlier, which may contain conditions like checking whether the product is active (IsActive). The Expression.Lambda&amp;gt; call generates a Func, meaning a function that takes a Product as input and returns a boolean value, determining whether the product satisfies the filtering criteria.&lt;/p&gt;

&lt;p&gt;Next, this lambda expression is passed to the Where method of the Products DbSet in dbContext. The Where method applies this filter to the product records in the database. It creates a query that retrieves only the products matching the conditions defined in the lambda expression.&lt;/p&gt;

&lt;p&gt;Finally, the ToListAsync() method asynchronously executes the query and retrieves the matching products as a list. This list is then returned as part of an HTTP 200 OK response using Results.Ok(data). The result is the filtered list of products, which is sent back as the API's response.&lt;/p&gt;

&lt;p&gt;In order to test it, just run the application and send the following GET request with Body via Postman:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o8ukgvgk07ufewqitrv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o8ukgvgk07ufewqitrv.gif" alt="Expression tree is active" width="706" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This approach is useful for us when building queries dynamically, as it allows the flexibility to add conditions based on which filters are provided.&lt;/p&gt;

&lt;p&gt;Here is how your LINQ expression should look after compiling your expression tree:&lt;br&gt;
&lt;code&gt;{x =&amp;gt; (True AndAlso (x.IsActive == True))}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So far, we have implemented the easiest property, which has two values: true or false. But how about other properties like categories, names, prices, etc.? Users are also able to not pick a product based on whether it is active or not but pick, for example, based on its category field. We allow users to provide multiple categories at the same time. That is why we implemented it as an array in our &lt;strong&gt;ProductSearchCategory&lt;/strong&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (productSearch.Categories is not null &amp;amp;&amp;amp; productSearch.Categories.Any())
{
    //x.Category
    MemberExpression memberExp = Expression.Property(parameterExp, nameof(Product.Category));
    Expression orExpression = Expression.Constant(false);
    foreach (var category in productSearch.Categories)
    {
        var constExp = Expression.Constant(category.Name);
        BinaryExpression binaryExp = Expression.Equal(memberExp, constExp);
        orExpression = Expression.OrElse(orExpression, binaryExp);
    }
    predicate = Expression.AndAlso(predicate, orExpression);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is adding dynamic filtering for product categories. It first checks if the &lt;code&gt;Categories&lt;/code&gt; in the &lt;code&gt;productSearch&lt;/code&gt; object is not null and contains any items. If so, it proceeds to build a dynamic expression to filter products by category.&lt;/p&gt;

&lt;p&gt;It starts by accessing the &lt;code&gt;Category&lt;/code&gt; property of the &lt;code&gt;Product&lt;/code&gt; class through an expression. This member expression represents &lt;code&gt;x =&amp;gt; x.Category&lt;/code&gt;, where &lt;code&gt;x&lt;/code&gt; is an instance of &lt;code&gt;Product&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An initial &lt;code&gt;orExpression&lt;/code&gt; is set to &lt;code&gt;false&lt;/code&gt;. This will serve as the base for the dynamic category comparison. It uses a loop to iterate over each category in &lt;code&gt;productSearch.Categories&lt;/code&gt;. For each category, a constant expression with the category name is created, and a binary expression checks if the product's &lt;code&gt;Category&lt;/code&gt; equals this name.&lt;/p&gt;

&lt;p&gt;The binary expressions are then combined using &lt;code&gt;OrElse&lt;/code&gt;, meaning that if the product matches any of the given categories, the condition becomes true. After processing all categories, the combined &lt;code&gt;orExpression&lt;/code&gt; is appended to the main &lt;code&gt;predicate&lt;/code&gt; with &lt;code&gt;AndAlso&lt;/code&gt;. This means the overall predicate will now check both the previous conditions and whether the product's category matches any of the categories in the search criteria.&lt;/p&gt;

&lt;p&gt;This approach allows for dynamically filtering products by multiple categories, and it integrates the category filtering into the existing predicate.&lt;/p&gt;

&lt;p&gt;At the end of the last code, you would get a LINQ expression that represents a lambda function used to filter products based on dynamic conditions. This expression can be translated into a predicate for use in a LINQ query, which can be applied to your ProductDbContext or any IQueryable.&lt;/p&gt;

&lt;p&gt;The LINQ expression, in this case, would be a combination of logical operations (AND and OR) that filter products. Specifically, it looks like this in pseudocode:&lt;br&gt;
&lt;code&gt;products.Where(x =&amp;gt; (x.Category == "Category1" || x.Category == "Category2" || ...) &amp;amp;&amp;amp; other conditions)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If a  user provides both (isActive and categories) then we should get the following lambda expression:&lt;br&gt;
&lt;code&gt;{x =&amp;gt; ((True AndAlso (x.IsActive == True)) AndAlso (((False OrElse (x.Category == "TV")) OrElse (x.Category == "Some Other")) OrElse (x.Category == "Mobile")))}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxl0q473jwy1mb240ijt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxl0q473jwy1mb240ijt.gif" alt="Expression tree categories" width="706" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We follow the same approach for the Names field. Here is our code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (productSearch.Names is not null &amp;amp;&amp;amp; productSearch.Names.Any())
{
    //x.Name
    MemberExpression memberExp = Expression.Property(parameterExp, nameof(Product.Name));
    Expression orExpression = Expression.Constant(false);
    foreach (var productName in productSearch.Names)
    {
        var constExp = Expression.Constant(productName.Name);
        BinaryExpression binaryExp = Expression.Equal(memberExp, constExp);
        orExpression = Expression.OrElse(orExpression, binaryExp);
    }
    predicate = Expression.AndAlso(predicate, orExpression);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code snippet dynamically builds a filtering condition for product names using expression trees. It first checks if the &lt;code&gt;productSearch.Names&lt;/code&gt; property is not null and contains any items. If there are product names to filter by, it proceeds to build an expression for comparing the &lt;code&gt;Name&lt;/code&gt; property of the &lt;code&gt;Product&lt;/code&gt; entity.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;memberExp&lt;/code&gt; expression refers to the &lt;code&gt;Name&lt;/code&gt; property of the &lt;code&gt;Product&lt;/code&gt; (&lt;code&gt;x.Name&lt;/code&gt; in a lambda expression). An initial expression, &lt;code&gt;orExpression&lt;/code&gt;, is created, starting as &lt;code&gt;false&lt;/code&gt;. This &lt;code&gt;orExpression&lt;/code&gt; will be updated in a loop to accumulate comparisons for each name in &lt;code&gt;productSearch.Names&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Within the loop, for each name in the &lt;code&gt;productSearch.Names&lt;/code&gt; collection, a constant expression is created from the product name. A binary expression is then formed to check if the product's &lt;code&gt;Name&lt;/code&gt; equals the current name from the search. The loop builds up a series of &lt;code&gt;OR&lt;/code&gt; conditions using &lt;code&gt;Expression.OrElse&lt;/code&gt;, which creates a logical OR operation between the current &lt;code&gt;orExpression&lt;/code&gt; and the new comparison.&lt;/p&gt;

&lt;p&gt;After the loop, the final &lt;code&gt;orExpression&lt;/code&gt; represents a chain of OR conditions where the product's &lt;code&gt;Name&lt;/code&gt; must match one of the names in &lt;code&gt;productSearch.Names&lt;/code&gt;. This expression is combined with the existing &lt;code&gt;predicate&lt;/code&gt; using &lt;code&gt;Expression.AndAlso&lt;/code&gt;, ensuring that the name filter is applied along with any other conditions previously defined in the &lt;code&gt;predicate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Long story short, our block of code dynamically constructs a query filter that matches products based on their &lt;code&gt;Name&lt;/code&gt;, allowing for multiple possible names from the &lt;code&gt;productSearch.Names&lt;/code&gt; collection.&lt;/p&gt;

&lt;p&gt;If the User provides only Names from the Body of the query, we will get approximately the following lambda expression at the end:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{x =&amp;gt; (True AndAlso (((False OrElse (x.Name == "LG")) OrElse (x.Name == "LG2")) OrElse (x.Name == "Samsung")))}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we get all filter parameters like isActive, categories, and names from the request body, we will get the following lambda expression at the end:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{x =&amp;gt; (((True AndAlso (x.IsActive == True)) AndAlso (((False OrElse (x.Category == "TV")) OrElse (x.Category == "Some Other")) OrElse (x.Category == "Mobile"))) AndAlso (((False OrElse (x.Name == "LG")) OrElse (x.Name == "LG2")) OrElse (x.Name == "Samsung")))}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is what it looks like when running the application and sending the query:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgprjkw3satob7iczpdr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgprjkw3satob7iczpdr.gif" alt="Expression tree names" width="706" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final argument for our dynamic filtering is Price. It is a complex object which consists of min and max values. The user should be able to provide any of them, both or none of them. That is why we designed it with nullable parameters.&lt;/p&gt;

&lt;p&gt;Here is what our code implementation looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (productSearch.Price is not null)
{
    //x.Price 400
    MemberExpression memberExp = Expression.Property(parameterExp, nameof(Product.Price));
    //x.Price&amp;gt;=min
    if (productSearch.Price.Min is not null)
    {
        var constExp = Expression.Constant(productSearch.Price.Min);
        var binaryExp = Expression.GreaterThanOrEqual(memberExp, constExp);
        predicate = Expression.AndAlso(predicate, binaryExp);
    }
    //(x.Price&amp;gt;=min &amp;amp;&amp;amp; x.Price.Max&amp;lt;=max)
    if (productSearch.Price.Max is not null)
    {
        var constExp = Expression.Constant(productSearch.Price.Max);
        var binaryExp = Expression.LessThanOrEqual(memberExp, constExp);
        predicate = Expression.AndAlso(predicate, binaryExp);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code dynamically constructs a predicate for filtering products based on their &lt;code&gt;Price&lt;/code&gt; range using expression trees. It starts by checking if the &lt;code&gt;productSearch.Price&lt;/code&gt; object is not null, which indicates that a price filter is applied.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;memberExp&lt;/code&gt; expression is created to represent the &lt;code&gt;Price&lt;/code&gt; property of the &lt;code&gt;Product&lt;/code&gt; (&lt;code&gt;x.Price&lt;/code&gt;). This expression is used to compare the product's price against the minimum and maximum values in the &lt;code&gt;productSearch.Price&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;If the minimum price (&lt;code&gt;productSearch.Price.Min&lt;/code&gt;) is provided (not null), an expression is built to check if the product's &lt;code&gt;Price&lt;/code&gt; is greater than or equal to this minimum value. This condition is added to the overall &lt;code&gt;predicate&lt;/code&gt; using &lt;code&gt;Expression.AndAlso&lt;/code&gt;, meaning the product must satisfy this condition to be included in the results.&lt;/p&gt;

&lt;p&gt;Similarly, if the maximum price (&lt;code&gt;productSearch.Price.Max&lt;/code&gt;) is provided, another expression is constructed to check if the product's &lt;code&gt;Price&lt;/code&gt; is less than or equal to the maximum value. This condition is also combined with the existing &lt;code&gt;predicate&lt;/code&gt; using &lt;code&gt;Expression.AndAlso&lt;/code&gt;, ensuring that both the minimum and maximum price conditions are applied.&lt;/p&gt;

&lt;p&gt;Long story short, the code builds a predicate that filters products by a specified price range, ensuring that products have a price greater than or equal to the minimum (if provided) and less than or equal to the maximum (if provided).&lt;/p&gt;

&lt;p&gt;If the User provides only Price from the Body of the query, we will get approximately the following lambda expression at the end:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{x =&amp;gt; ((True AndAlso (x.Price &amp;gt;= 400)) AndAlso (x.Price &amp;lt;= 5000))}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we get all filter parameters like IsActive, Categories, Names, and Price from the request body, we will get the following lambda expression at the end:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{x =&amp;gt; (((((True AndAlso (x.IsActive == True)) AndAlso (((False OrElse (x.Category == "TV")) OrElse (x.Category == "Some Other")) OrElse (x.Category == "Mobile"))) AndAlso (((False OrElse (x.Name == "LG")) OrElse (x.Name == "LG2")) OrElse (x.Name == "Samsung"))) AndAlso (x.Price &amp;gt;= 400)) AndAlso (x.Price &amp;lt;= 5000))}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is what it looks like when running the application and sending the query:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiocbcl6tnvg15y8h5mkq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiocbcl6tnvg15y8h5mkq.gif" alt="Expression tree price" width="706" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The elegant ending&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article serves as a practical continuation of the previous tutorial on C# expression trees, focusing on their real-world usage within an ASP.NET Core web API. It explores the creation of dynamic filtering functionality using minimal API, Entity Framework Core (EF Core), and expression trees.&lt;/p&gt;

&lt;p&gt;The project involves building a product database with dynamic filtering capabilities, such as filtering by product attributes like &lt;code&gt;IsActive&lt;/code&gt;, &lt;code&gt;Category&lt;/code&gt;, &lt;code&gt;Name&lt;/code&gt;, and &lt;code&gt;Price&lt;/code&gt;. The use of expression trees is highlighted to construct flexible, dynamic queries without hardcoding-specific filters.&lt;/p&gt;

&lt;p&gt;The setup begins with an ASP.NET Core Web API using an in-memory database for storage, although other EF Core-supported databases could be used. The article emphasizes using minimal API over traditional controllers for simplicity and performance and guides the user through the necessary steps, including setting up the database context (&lt;code&gt;DbContext&lt;/code&gt;) and initializing data.&lt;/p&gt;

&lt;p&gt;One of the core features demonstrated is how expression trees are used to build predicates dynamically. For example, when filtering by the &lt;code&gt;IsActive&lt;/code&gt; property, the system checks whether the user provided this filter and then dynamically constructs a condition that compares the product's &lt;code&gt;IsActive&lt;/code&gt; status with the provided value. The process is extended to handle dynamic filtering of other properties such as &lt;code&gt;Category&lt;/code&gt;, &lt;code&gt;Name&lt;/code&gt;, and &lt;code&gt;Price&lt;/code&gt;, each of which allows flexible criteria for querying.&lt;/p&gt;

&lt;p&gt;By using expression trees, the article illustrates how complex and flexible queries can be constructed without writing multiple hardcoded query methods. The example of filtering products by &lt;code&gt;Name&lt;/code&gt; and &lt;code&gt;Category&lt;/code&gt; demonstrates how logical &lt;code&gt;OR&lt;/code&gt; conditions can be combined dynamically, depending on user input, resulting in concise and reusable query logic.&lt;/p&gt;

&lt;p&gt;Additionally, the price filtering is handled by checking both minimum and maximum values and dynamically adjusting the predicate to include only those products within the specified price range.&lt;/p&gt;

&lt;p&gt;In conclusion, this article demonstrates the power of expression trees in building dynamic, flexible queries in C# applications. It provides hands-on code examples of using expression trees to construct queries for an ASP.NET Core web API, offering a practical way to manage complex, real-world scenarios like filtering product databases based on varying user input.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>expressiontrees</category>
      <category>tutorial</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Solid Introduction to Expression Trees in C#</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Sat, 28 Sep 2024 11:15:41 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/solid-introduction-to-expression-trees-in-c-1c4i</link>
      <guid>https://dev.to/turalsuleymani/solid-introduction-to-expression-trees-in-c-1c4i</guid>
      <description>&lt;p&gt;Expression trees are one of the complex topics in C#/.NET that needs to be understood. They represent code in a tree-like data structure, where each node is an expression (such as a method call, binary operation, or constant value). They allow you to construct, examine, and execute code dynamically at runtime.&lt;/p&gt;

&lt;p&gt;Expression trees are particularly useful for creating dynamic code, analyzing code at runtime, and enabling frameworks like LINQ to SQL and Entity Framework to translate C# code into SQL queries or other operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr41td9iq65o4c6fkmlyd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr41td9iq65o4c6fkmlyd.png" alt="expression tree" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Expression trees are composed of nodes, each representing a specific element of a program (e.g., a method call, a lambda expression, or a binary operation like + or -).&lt;/p&gt;

&lt;p&gt;Before diving into the details of technical implementation, let’s try to understand the use cases of Expression trees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. LINQ Providers:&lt;/strong&gt; In LINQ to SQL and Entity Framework, expression trees are used to parse LINQ queries and translate them into SQL statements. When you write a LINQ query like dbContext.Products.Where(p =&amp;gt; p.Price &amp;gt; 100), the LINQ provider examines the expression tree representing p =&amp;gt; p.Price &amp;gt; 100 and translates it into a SQL query (SELECT * FROM Products WHERE Price &amp;gt; 100).&lt;br&gt;
&lt;strong&gt;2. Dynamic Query Construction:&lt;/strong&gt; Expression trees allow developers to dynamically construct queries at runtime. For example, you can build complex search conditions based on user input, dynamically combining predicates using expressions like Expression. Also Expression.OrElse.&lt;br&gt;
&lt;strong&gt;3. Meta-Programming:&lt;/strong&gt; Expression trees enable meta-programming scenarios where you can inspect and manipulate code at runtime. You can analyze expression trees to understand the structure of code, allowing you to write tools that generate or transform code.&lt;br&gt;
&lt;strong&gt;4. Building Dynamic LINQ Queries:&lt;/strong&gt; Expression trees allow you to construct dynamic LINQ queries by building predicates based on conditions at runtime. This is useful when constructing search filters or complex queries based on dynamic user input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var parameter = Expression.Parameter(typeof(Product), "p"); 
 var property = Expression.Property(parameter, "Price"); 
 var constant = Expression.Constant(100);  
var condition = Expression.GreaterThan(property, constant); 
var lambda = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(condition, parameter);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Custom Rule Engines:&lt;/strong&gt; Expression trees are used in rule engines where business rules are evaluated dynamically. Developers can build, compile, and execute rules represented by expression trees based on data at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do we have as advanced Features?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expression Visitor: An ExpressionVisitor is a class in the System.Linq.Expressions namespace that allows you to traverse and modify expression trees. This is useful for scenarios where you need to analyze or modify parts of an expression tree.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class CustomExpressionVisitor : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {

        // Example: Change all addition operations to multiplication
        if (node.NodeType == ExpressionType.Add)
        {
            return Expression.Multiply(node.Left, node.Right);
        }
        return base.VisitBinary(node);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Expression Trees for LINQ Query Optimization: Expression trees can be used to optimize LINQ queries at runtime. By analyzing the structure of a LINQ query, frameworks can choose to cache certain expressions, rewrite inefficient queries, or perform other optimizations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Combining Expressions: You can combine multiple expressions dynamically to create more complex queries. For instance, you can dynamically build predicates using Expression.AndAlso Expression.OrElse.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; expr1 = p =&amp;gt; p.Price &amp;gt; 100;

Expression&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt; expr2 = p =&amp;gt; p.Category == "TV";

var combined = Expression.Lambda&amp;lt;Func&amp;lt;Product, bool&amp;gt;&amp;gt;(

Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expression trees are created using the types defined in the System.Linq.Expressions namespace. The most common classes include.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expression:&lt;/strong&gt; The base class for all nodes in an expression tree.&lt;br&gt;
&lt;strong&gt;LambdaExpression:&lt;/strong&gt; Represents lambda expressions.&lt;br&gt;
&lt;strong&gt;BinaryExpression:&lt;/strong&gt; Represents binary operations (e.g., +, -, &lt;em&gt;, /).&lt;br&gt;
**MethodCallExpression:&lt;/em&gt;* Represents method calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to build them?&lt;/strong&gt;&lt;br&gt;
You can create expression trees manually using factory methods such as Expression.Add(), Expression.Constant(), and Expression.Lambda(). For example, to represent the expression x + 1 where x is a parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ParameterExpression param = Expression.Parameter(typeof(int), "x");

ConstantExpression constant = Expression.Constant(1);

BinaryExpression body = Expression.Add(param, constant);

Expression&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt; lambda = Expression.Lambda&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;(body, param);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once an expression tree is built, it can be compiled into executable code using Compile().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var compiledLambda = lambda.Compile();

int result = compiledLambda(5);  // result = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Long story short, we have the following steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Construction&lt;/strong&gt;: Expression trees are built using System.Linq.Expressions.Expression static methods such as Expression.Add(), Expression.Call(), and Expression.Lambda(). Each method constructs a node in the expression tree.&lt;br&gt;
&lt;strong&gt;Compilation&lt;/strong&gt;: Once the expression tree is built, you can compile it into executable code using the Compile() method, which turns the expression into a delegate that can be invoked.&lt;br&gt;
&lt;strong&gt;Execution&lt;/strong&gt;: After compiling, the expression behaves like any regular delegate, and you can invoke it with arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any limitations? Of course. Here they are:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;No Full Language Support:&lt;/strong&gt; While expression trees cover a wide range of C# constructs, they don’t support all C# features. For example, loops, try-catch blocks, and certain other flow-control constructs cannot be represented using expression trees.&lt;br&gt;
&lt;strong&gt;Performance Overhead:&lt;/strong&gt; Constructing and compiling expression trees can introduce a performance overhead compared to using compiled code. However, once compiled, the generated delegate executes with minimal overhead.&lt;br&gt;
&lt;strong&gt;Complexity:&lt;/strong&gt; Managing and manipulating expression trees for complex logic can become cumbersome due to their hierarchical and low-level nature. This is why they are often used in combination with higher-level abstractions.&lt;/p&gt;

&lt;p&gt;In the end, let’s cover real-world examples of using Expression Trees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entity Framework Core:&lt;/strong&gt; EF Core uses expression trees to translate LINQ queries into SQL queries. The LINQ queries written in C# are parsed into expression trees, and then EF Core translates these trees into the corresponding SQL.&lt;br&gt;
**Custom Query Builders: **You can use expression trees to build custom query builders that generate complex search queries based on dynamic conditions. For example, if you’re building a search filter for a web application, you could use expression trees to construct the query based on the user’s input dynamically.&lt;br&gt;
**Unit of Work and Repository Patterns: **Expression trees are often used in repository patterns to implement dynamic filtering, sorting, and pagination in a reusable way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Expression trees are an invaluable tool when you need to dynamically create, manipulate, or inspect code in a flexible and efficient way. They are particularly important for frameworks that rely on dynamic code generation, such as LINQ providers and rule engines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to dive deeper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;TuralSuleymaniTech&lt;/a&gt; YouTube channel, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>tutorial</category>
      <category>expressiontrees</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Resolving Race Conditions and Critical Sections in C#</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Fri, 30 Aug 2024 08:38:54 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/resolving-race-conditions-and-critical-sections-in-c-1f24</link>
      <guid>https://dev.to/turalsuleymani/resolving-race-conditions-and-critical-sections-in-c-1f24</guid>
      <description>&lt;p&gt;A race condition in C# occurs when two or more threads access shared data simultaneously, and the outcome of the program depends on the unpredictable timing of these threads. This can lead to inconsistent or incorrect results, making race conditions a critical problem in multi-threaded applications.&lt;/p&gt;

&lt;p&gt;In this article, we will learn everything in practice and will try not just to understand but also to resolve the race condition and critical section problems in .NET.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Race Conditions Occur?&lt;/strong&gt;&lt;br&gt;
Race conditions typically occur when the following conditions are met.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared Resource:&lt;/strong&gt; Two or more threads are trying to read, write, or modify the same shared resource (e.g., a variable, object, or file).&lt;br&gt;
&lt;strong&gt;Concurrent Execution:&lt;/strong&gt; The threads execute concurrently without proper synchronization mechanisms to control their access to the shared resource.&lt;br&gt;
Race conditions occur when multiple threads concurrently access and modify shared data, leading to unpredictable results.&lt;/p&gt;

&lt;p&gt;They arise due to the lack of synchronization, where threads interleave in a way that causes operations to be performed out of the expected order.&lt;/p&gt;

&lt;p&gt;A critical section in C# refers to a block of code that must be executed by only one thread at a time to prevent data corruption or inconsistent results due to concurrent access. When multiple threads access shared resources, such as variables or objects, and at least one thread modifies those resources, a critical section ensures that only one thread can execute the code block that accesses the shared resource at a time. This is crucial for maintaining the integrity of the shared data.&lt;/p&gt;

&lt;p&gt;Let's directly switch to our example below and explore both worlds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Transaction
{
    public bool IsDone { get; set; }
    public void Transfer(decimal amount)
    {
        if (!IsDone)//critical section
        {
            Console.WriteLine($"Transaction operation started in thread number = {Environment.CurrentManagedThreadId}");
            TransferInternally(amount);
            Console.WriteLine($"Transaction operation ended in thread number = {Environment.CurrentManagedThreadId}");
            IsDone = true;
        }
    }
    private void TransferInternally(decimal amount)
    {
        Console.WriteLine($"TransferInternally in thread...{Environment.CurrentManagedThreadId}, the amount = {amount}");
        Console.WriteLine($"TransferInternally is done in thread...{Environment.CurrentManagedThreadId}, the amount = {amount}");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the provided code, the critical section and the race condition problem relate to how multiple threads might interact with the Transaction class, particularly with the IsDone property and the Transfer method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Critical Section&lt;/strong&gt;&lt;br&gt;
A critical section is a part of the code that accesses shared resources (in this case, the IsDone property) and must not be executed by more than one thread at a time. The critical section in your code is.&lt;/p&gt;

&lt;p&gt;This code block is critical because it checks and updates the IsDone property. If multiple threads access this code simultaneously without proper synchronization, it could lead to inconsistent or incorrect behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Race Condition Problem&lt;/strong&gt;&lt;br&gt;
A race condition occurs when a program's outcome depends on the timing or sequence of threads executing. In this code, a race condition could happen if multiple threads call the Transfer method at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario Leading to a Race Condition&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thread 1 checks the IsDone property and finds it to be false.&lt;/li&gt;
&lt;li&gt;Thread 1 proceeds with the transaction, outputting the start message and entering the TransferInternally method.&lt;/li&gt;
&lt;li&gt;Thread 2 then checks the IsDone property before Thread 1 has finished and still finds it to be false.&lt;/li&gt;
&lt;li&gt;Thread 2 also proceeds with the transaction, despite Thread 1 already handling it.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void Main(string[] args)
{
    Transaction2 transaction = new Transaction2();
    for (int i = 0; i &amp;lt; 10; i++)
    {
        Task.Run(() =&amp;gt;
        {
            transaction.Transfer(3000);
        });
    }
    Console.ReadLine();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The provided code demonstrates how a race condition problem can occur when multiple threads simultaneously attempt to execute the Transfer method of the Transaction class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation of the Code&lt;/strong&gt;&lt;br&gt;
Transaction Instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Transaction transaction = new Transaction();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, a single instance of the Transaction class is created. This instance is shared among all threads that will be created in the subsequent loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (int i = 0; i &amp;lt; 10; i++)
{
    Task.Run(() =&amp;gt;
    {
        transaction.Transfer(3000);
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loop runs 10 times, and each iteration starts a new task using Task. Run. Each task calls the Transfer method of the transaction object, attempting to transfer the amount of 3000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;br&gt;
Each Task. Run spawns a new thread (or reuses one from the thread pool) to execute the code within the lambda expression. Therefore, up to 10 threads might be running the Transfer method concurrently.&lt;/p&gt;

&lt;p&gt;Because there’s no synchronization mechanism like a lock statement, multiple threads could be executing this block simultaneously. This leads to several threads performing the transfer, outputting the start and end messages, and setting IsDone to true.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Race Condition Effect&lt;/strong&gt;&lt;br&gt;
The race condition occurs because the IsDone check and the subsequent operations are not atomic. This means that even if one thread sets IsDone to true, other threads might have already passed the check and are also executing the transfer, leading to multiple executions of what should be a one-time transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The outcome of the Race Condition&lt;/strong&gt;&lt;br&gt;
As a result of the race condition, you might see output that indicates the transaction was processed multiple times, even though the logic implies it should only happen once. Each thread will print its messages to the console, showing that multiple threads have entered the critical section and completed the transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F966ykhjr8c8v60c6g92n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F966ykhjr8c8v60c6g92n.png" alt="race condition output" width="524" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To prevent race condition problems and capture the critical section, we will use the &lt;strong&gt;lock&lt;/strong&gt; keyword. Of course, we have multiple ways to avoid these problems but the easiest one is using the lock keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Transaction2
{
    public bool IsDone { get; set; }
    private static readonly object _object = new object();
    public void Transfer(decimal amount)
    {
        lock(_object)
        {
            if (!IsDone)//should act as a single atomic operation
            {
                Console.WriteLine($"Transaction operation started in thread number = {Environment.CurrentManagedThreadId}");
                TransferInternally(amount);
                Console.WriteLine($"Transaction operation ended in thread number = {Environment.CurrentManagedThreadId}");
                IsDone = true;
            }

        }

    }

    private void TransferInternally(decimal amount)
    {
        Console.WriteLine($"TransferInternally in thread...{Environment.CurrentManagedThreadId}, the amount = {amount}");
        Console.WriteLine($"TransferInternally is done in thread...{Environment.CurrentManagedThreadId}, the amount = {amount}");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Transaction2 result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtv3cb8libw532cdd0fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtv3cb8libw532cdd0fb.png" alt="resolving race condition" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>tutorial</category>
      <category>racecondition</category>
      <category>criticalsection</category>
    </item>
    <item>
      <title>Advanced JS — Refactoring Toward Objects</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Sun, 18 Aug 2024 17:27:29 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/advanced-js-refactoring-toward-objects-58ef</link>
      <guid>https://dev.to/turalsuleymani/advanced-js-refactoring-toward-objects-58ef</guid>
      <description>&lt;p&gt;Javascript has several object creation syntaxes, but object configurations (in a sense, associative arrays) occupy a special place among them. This modeling approach is often referred to as object configurations because it contains more configuration information when used, similar to JSON syntax in practice. When object configurations do not store motion in themselves, they act as an associative array to it. Associative arrays are another form of an array whose index is usually a form of an array containing more meaningful phrases.&lt;/p&gt;

&lt;p&gt;PS: You can download the source codes of &lt;a href="https://github.com/TuralSuleymani/Refactoring2Objects" rel="noopener noreferrer"&gt;the project here&lt;/a&gt;. Don’t forget to put a star on the repo if you like it.&lt;/p&gt;

&lt;p&gt;Author’s note: One of the top 10 JS topics we used most when programming a payment terminal was object configurations. When a new provider was integrated into the terminal, information such as the added provider’s identifier, min-max payment limit, which provider group it belongs to, the names of parameters that will come and go during the request-response, etc., were stored in the object configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "__type": "pages",
    "__objects": [{
        "pageId": "30492001",
        "title": "",
        "useOnline": "true", // Онлай авторизация false-нет, true-да.
        "__objects": [{
            "__type": "controls",
            "__objects": [{
                "header": "Xahiş edirik, 15 rəqəmli kodu daxil edin", // Приветствие
                "footer": "", // Подпись под полем ввода номера
                "mask": "", // Маска поля ввода
                "name": "account",
                "nobr": "false",
                "regexp": "^\\d{15}$",
                "strip": "True", // Удаление доп. символов в маске например кавычки. true - удалить false - нет
                "type": "text_input"
            }, {
                "layout": "DG", // Язык клавиатуры по умолчанию DG - цифровая, Буквенная ( AL - английский язык, ALC - Всключенный Capslock, ALS - Зажат Shift, ALR - Русская раскладка, ALRC - Русская с Capslock, ALRS - Русская с Shiftom (Первая буква))
                "type": "keyboard"
            }]
        }]
    }]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PS: User-defined arrays just store information, not specific actions. But object configurations store both associative data and actions (methods). Therefore, it is normal that you will not come across the term associative array in many JS literature.&lt;/p&gt;

&lt;h2&gt;
  
  
  How are object configurations created?
&lt;/h2&gt;

&lt;p&gt;Object configurations are mainly declared using the {} symbol. You will rarely come across a variant written with a new Object(). Object configurations usually store the configuration of a particular object according to its name, and methods for manipulating those configurations. This declaration of an object allows concepts to be viewed as objects.&lt;/p&gt;

&lt;p&gt;You can use it as an associative array, simply storing values in object configurations. When developing large applications, it may be very necessary for the object to act as an associative array. So getting some information from the backend can be expensive for your application. At this time, we store static information in the form of an associative array. When we programmed the Emanat terminal, we saved the configuration of the providers in the form of an associative array. If the provider names on the terminal’s home page came from the backend, the terminal would be heavily loaded. But reading them from a JS associative array gives us maximum speed.&lt;/p&gt;

&lt;p&gt;There are some rules to be aware of when creating object configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To protect the internal structure of the object from external interference, the variables of the object are usually declared with the sign _.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let person = {
    _name: "Hesen",
    _surname: "Mammadov",
    changeName: function (name) {
        //validate here
        this._name = name;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Following the OOP paradigm, the internal variables of an object should only be allowed to change via a method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is possible to dynamically add an absent field to the object. Because object configurations can also act as just another form of arrays!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//this code however works fine...
person.age = 45;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By configuring the object, it is possible to prohibit dynamically adding objects to its, iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The variable of the object, unlike normal variables, consists of two or more words and can be written separately. In this case, we can simply refer to it using the array syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let person = {
    _name: "Hesen",
    _surname: "Mammadov",
    'full info':'Full info here',
    changeName: function (name) {
        //validate here
        this._name = name;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the property names of the object follow the naming rules of variables, then we can write them in quotes or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let person = {
    '_name': "Hesen",
    '_surname': "Mammadov",
    'full info':'Full info here',
    changeName: function (name) {
        //validate here
        this._name = name;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What we learned in practice
&lt;/h2&gt;

&lt;p&gt;To practice what we’ve learned, we’ll try to put together a small app like the one below using javascript. We will create not only the animation on the page but all the HTML elements using Js so that we can better understand the object configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fml8y2pvwv2qd4wyf3f1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fml8y2pvwv2qd4wyf3f1v.png" alt="gif image" width="600" height="267"&gt;&lt;/a&gt;&lt;br&gt;
In the first version of the program, the following functional codes were written to create the container and buttons of the page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createButton(txt, classList) {
    let btn = document.createElement('button');
    btn.innerText = txt;
    for (let f of classList) {
        btn.classList.add(f);
    }
    return btn;
}

function createImage(src, width) {
    let img = document.createElement('img');
    img.src = src;
    img.style.width = width;
    return img;
}

function createContainer() {
    let dvContainer = document.createElement('div');
    dvContainer.className = 'controls';
    return dvContainer;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These functions are ultimately used by the **loadAllHtml() **function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function loadAllHtml() {
    let img = createImage('img/going.gif', '20%');
    document.body.insertBefore(img, document.body.firstChild);
    let dvContainer = createContainer();
    document.body.insertBefore(dvContainer, document.getElementById('scr'));
    let btn1 = createButton('Start', ['btn', 'btn-start']);
    let btn2 = createButton('Stop', ['btn', 'btn-stop']);
    let btn3 = createButton('Reset', ['btn', 'btn-reset']);
    dvContainer.appendChild(btn1);
    dvContainer.appendChild(btn2);
    dvContainer.appendChild(btn3);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our function called activeAllElements() is designed to connect to events. this function allows us to bind events to buttons on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function activeAllElements() {
    let interval = null;
    let isRunning = false;
    document.getElementsByClassName('btn-start')[0].addEventListener('click', function() {
        if (!isRunning) {
            interval = setInterval(() =&amp;gt; {
                let img = document.querySelector('img');
                let iml = parseInt(getComputedStyle(img).marginLeft);
                iml += 2;
                isRunning = true;
                img.style.marginLeft = `${iml}px`;
            }, 20);
        }
    });
    document.getElementsByClassName('btn-stop')[0].addEventListener('click', function() {
        if (interval != null) {
            clearInterval(interval);
            isRunning = false;
        }
    });
    document.getElementsByClassName('btn-reset')[0].addEventListener('click', function() {
        if (interval != null) {
            clearInterval(interval);
            isRunning = false;
            document.querySelector('img').style.marginLeft = 0;
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the codes we wrote work, they have very serious gaps. Let’s list some of these gaps,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Functions like createButton() and createImage() are very poorly written functions. They do not allow solving all problems from a class in this example. Since we are talking about the HTML element in the end, these functions can be combined to create a final function, which we have done in the OOP version.&lt;/li&gt;
&lt;li&gt;The registration process for events is not perfect. Because the codes we write are strongly dependent on the context, it is almost impossible to use those functions in another similar project.&lt;/li&gt;
&lt;li&gt;The activeAllElements() function does not completely reflect reality in terms of both naming and operation. Because there are codes here just for the sake of work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Refactoring towards object&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactoring is the process of improving the code of a program without changing its functionality. That is, the program works correctly as it is, but the code is refined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To do proper refactoring in the code we write, we first need to do a proper separation of responsibility.&lt;/p&gt;

&lt;p&gt;According to the division of responsibilities, it is necessary to ensure the creation of objects on the page and the preparation of animation. We will create a separate object for each of these tasks. First, let’s look at our DOM object. This object will allow you to easily create DOM elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let dom = {
    createElement: function(tagName, className, cssProps) {
        //create dom element
        let element = document.createElement(tagName);
        //check if this element is valid html element
        if (element != null) {
            //if so, then validate classname existance
            if (this._isValidValue(className)) {
                element.className = className;
            }
            //enumerate all css properties given as  object
            for (let f in cssProps) {
                //check if object key is valid attribute
                if (this._isValidAttr(f)) {
                    //then use it as attribute
                    element[f] = cssProps[f];
                }
                //otherwise,it is just style.Use it as style..
                else {
                    element.style[f] = cssProps[f];
                }
            }
        }
        return element;
    },
    _isValidValue: function(val) {
        return (typeof(val) !== "undefined" &amp;amp;&amp;amp; val)
    },
    _isValidAttr: function(attr) {
        return (attr == 'src' || attr == 'href' || attr == 'innerText' || attr == 'id');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we can create DOM elements, we can move on to the animation part. Object-oriented mechanism saves us from the concept of a global variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let animation = {
    _isRunning: false,
    _interval: null,
    _animatableElementInstance: null,
    animate: function(elementId, sec) {
        this._animatableElementInstance = document.getElementById(elementId);
        if (!this._isRunning) {
            this._interval = setInterval(function() {
                let element = document.getElementById(elementId);
                let imgML = parseInt(getComputedStyle(element).marginLeft);
                imgML += 1;
                element.style.marginLeft = `${imgML}px`;
            }, sec);
            this._isRunning = true;
        }
    },
    stopAnimate: function() {
        if (this._interval != null) {
            this._isRunning = false;
            clearInterval(this._interval);
        }
    },
    resetAnimate: function(elementId) {
        this.stopAnimate();
        let element = document.getElementById(elementId);
        element.style.marginLeft = 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end, we just rely on the functional aspect to create the elements on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function loadAllHtmlContent() {
    //create img
    let img = dom.createElement('img', 'img-basic', {
        'src': "going.gif",
        'width': "20%",
        'id': 'animetableImage'
    })
    //add it before script
    document.body.insertBefore(img, document.getElementById('scr'));
    //create container
    let divContainer = dom.createElement('div', 'controls');
    //with buttons
    let btn_start = dom.createElement('button', 'btn btn-start', {
        'innerText': 'start'
    });
    let btn_stop = dom.createElement('button', 'btn btn-stop', {
        'innerText': 'stop'
    });
    let btn_reset = dom.createElement('button', 'btn btn-reset', {
        'innerText': 'reset'
    });
    //add them to container
    divContainer.appendChild(btn_start);
    divContainer.appendChild(btn_stop);
    divContainer.appendChild(btn_reset);
    //append container after img
    document.body.after(img, divContainer);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After writing these codes, it is enough for us to add this code by simply opening the script tag inside the body tag on our required page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.addEventListener('DOMContentLoaded', function() {
    //create all html elements
    loadAllHtmlContent();
    document.querySelector('.btn-start').addEventListener('click', function() {
        animation.animate('animetableImage', 10);
    });
    document.querySelector('.btn-stop').addEventListener('click', function() {
        animation.stopAnimate();
    });
    document.querySelector('.btn-reset').addEventListener('click', function() {
        animation.resetAnimate('animetableImage');
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, each object performs only its operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to dive deeper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Regularly, I share my senior-level expertise on my &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;TuralSuleymaniTech &lt;/a&gt;YouTube channel, breaking down complex topics like .NET, Microservices, Apache Kafka, Javascript, Software Design, Node.js, and more into easy-to-understand explanations. Join us and level up your skills!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>refactoring</category>
      <category>oop</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Launched my Russian Version of Youtube Channel</title>
      <dc:creator>Tural Suleymani</dc:creator>
      <pubDate>Fri, 02 Aug 2024 07:16:07 +0000</pubDate>
      <link>https://dev.to/turalsuleymani/launched-my-russian-version-of-youtube-channel-5c73</link>
      <guid>https://dev.to/turalsuleymani/launched-my-russian-version-of-youtube-channel-5c73</guid>
      <description>&lt;p&gt;Dear friends,&lt;/p&gt;

&lt;p&gt;As you already know, I have a &lt;a href="https://www.youtube.com/@TuralSuleymaniTech" rel="noopener noreferrer"&gt;youtube channel&lt;/a&gt; (TuralSuleymaniTech) where I share my Senior level expertise with the latest .NET/C# and related topics&lt;/p&gt;

&lt;p&gt;The Russian version of my YouTube channel is now ready(TuralSuleymaniTechRU), and our first video has been released. It's not AI-generated, everything is filmed from scratch.&lt;/p&gt;

&lt;p&gt;You can subscribe and support the channel: &lt;a href="https://www.youtube.com/@TuralSuleymaniTechRU" rel="noopener noreferrer"&gt;TuralSuleymaniTechRU&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going forward, I'll try to create both English and Russian versions of the same content.&lt;/p&gt;

&lt;p&gt;PS: I should note that I haven't studied in a Russian-speaking environment and haven't taken any Russian language courses or training. Like with English, I'm self-taught in Russian. So, I'm quite okay with grammatical and conversational mistakes and don't feel any anxiety about it. &lt;/p&gt;

&lt;p&gt;The first lesson video:&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://www.youtube.com/watch?si=KWq5pdodVxVOkAKk&amp;amp;v=hN_v6QL8XwM&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;
      youtube.com
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Thanks in advance,&lt;br&gt;
Tural Suleymani&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>tutorial</category>
      <category>techtalks</category>
      <category>youtube</category>
    </item>
  </channel>
</rss>
