<?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: Alex Alves</title>
    <description>The latest articles on DEV Community by Alex Alves (@alexalvess).</description>
    <link>https://dev.to/alexalvess</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%2F537180%2F8dbecc61-9e11-4cf1-8fe2-01ab794c03d5.jpeg</url>
      <title>DEV Community: Alex Alves</title>
      <link>https://dev.to/alexalvess</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexalvess"/>
    <language>en</language>
    <item>
      <title>An Overview of Distributed Programming and Systems</title>
      <dc:creator>Alex Alves</dc:creator>
      <pubDate>Mon, 29 Jan 2024 13:25:12 +0000</pubDate>
      <link>https://dev.to/alexalvess/an-overview-of-distributed-programming-and-systems-iga</link>
      <guid>https://dev.to/alexalvess/an-overview-of-distributed-programming-and-systems-iga</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fckrnkcin9zw2203vcdkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fckrnkcin9zw2203vcdkm.png" alt="Image description" width="720" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple way to define/describe is the same system can be executed in many environments, where you can distribute the execution/process of some flow. Besides this, you need to build algorithms that can be executed in this environment. Let’s see some overview concepts, below!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this important?
&lt;/h2&gt;

&lt;p&gt;When you work with high processing power, distributing it is an excellent way to improve the utilization of computational resources without spending all your resources on the machine. You allow your system to process things in different environments/nodes/machines/servers.&lt;/p&gt;

&lt;p&gt;When we use a non-distributed architecture, we have just one POD/VM (the first called) to execute all the flow:&lt;/p&gt;

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

&lt;p&gt;On the other hand, when we use distributed architecture, we can divide the responsibility to execute all the processes. Where we use all PODs/VMs to do this:&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Distributed programming is the art of solving the same problem that you can solve on a single computer using multiple computers. [Mikito Takada]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Horizontal Scalability&lt;/li&gt;
&lt;li&gt;Availability: failures do not impact other modules/services&lt;/li&gt;
&lt;li&gt;Performance: distributed tasks may get a great result&lt;/li&gt;
&lt;li&gt;Resilience: distributed processes and data may be more failure resistance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complexity: requires advanced knowledge about distributed programming, network, and resource manager&lt;/li&gt;
&lt;li&gt;Consistency: mainly in a high concurrency&lt;/li&gt;
&lt;li&gt;Communication: may introduce latency when transmitting some data&lt;/li&gt;
&lt;li&gt;Infrastructure: you should know about networking to define the best way to reduce latency, cost, and degradation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Topologies
&lt;/h2&gt;

&lt;p&gt;When we talk about distributed systems, we talk about strategies for following, and we need to answer the following question by ourselves:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;* Are we confident in the system/service, to process some piece of journey/flow correctly?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If the answer is “yes”, we don’t need some app to control the flow, we need to accept it, and we will get a decentralized system. If the answer is “no”, we need something to control all the journey/flow, to tell which service/environment will execute something, and then we'll get a centralized system. Both are distributed but in different ways (or Topologies). Let’s talk about it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Broker (Decentralized)
&lt;/h3&gt;

&lt;p&gt;The message flow is distributed across the journey/components. This topology is very useful if you do not want a central event orchestration. You only need to broadcast the message, someone consumes it and propagates another message, without other components knowing about the process. It’s all about the chaining of events. And, to see what happens if an event is published, you need an “alive documentation” to demonstrate it, like an EventStorming.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Points to Consider&lt;/strong&gt;&lt;br&gt;
🔴 Monitoring complexity&lt;br&gt;
🔴 Debbuging complexity&lt;br&gt;
🔴 Error handling&lt;br&gt;
🟢 Decoupling&lt;br&gt;
🟢 Flexibility&lt;br&gt;
🟢 Scalability&lt;br&gt;
🟢 High throughput&lt;/p&gt;

&lt;h3&gt;
  
  
  Mediator (Centralized)
&lt;/h3&gt;

&lt;p&gt;It is useful if you need some level of orchestration, like when you will do a rollout process (migrate functionalities of legacy to new application). Here, you have to pay attention to SPOF (Single Point of Failure), because all the processes will depend on your orchestration. Here we maybe see the Request-Reply pattern, in which the orchestration needs to wait for the service reply when he calls it.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Points to Consider&lt;/strong&gt;&lt;br&gt;
🔴 Single Point of Failure (SPOF)&lt;br&gt;
🔴 Scalability limitations&lt;br&gt;
🔴 Performance overhead&lt;br&gt;
🔴 Over-coupling&lt;br&gt;
🟢 Clearer visibility&lt;br&gt;
🟢 Simplified error handling&lt;br&gt;
🟢 Improved security&lt;/p&gt;

&lt;h3&gt;
  
  
  Sagas
&lt;/h3&gt;

&lt;p&gt;This is a pattern that helps us to do rollbacks in “distributed transactions”, used in both topologies like Choreographic (to broker topology) and Orchestration (to mediator topology).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Choreographic&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
When a process fails, the service publishes an event of failure, and all interested services consume it to do something (like "revert"), using the "compensation event" concept.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Orchestration&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Is almost the same thing as Choreographic, except it controls the failure service and calls directly all other points to "revert".&lt;/p&gt;

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

&lt;p&gt;In other words, we don’t have a real rollback, just a “compensation event”, because the side effects have already happened. And, looking at this we observe how this strategy impacts the system coordination and consistency. As the topology models the components' interaction, let’s see below how can we use the concurrency control to guarantee the consistency and integrity of each service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concurrency Controls
&lt;/h2&gt;

&lt;p&gt;It's something like a mechanism that ensures to control of multiple concurrent transactions. It thinks about the conflicts and how we can maintain data consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimistic
&lt;/h3&gt;

&lt;p&gt;This strategy considers the best scenarios possible because it assumes will happen infrequently and allows transactions to happen unsynchronized. However, you need to guarantee that the conflicts that will have don’t affect your system. Whether through exceptions or the ordering of actions that will happen, for example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pessimistic
&lt;/h3&gt;

&lt;p&gt;On the other hand, you can use a blockade strategy. In this case, we assume that conflicts will happen frequently and we block the part of the code for the first client to use it. We can use thread local safe or distributed lock for this, using something like Redis.&lt;/p&gt;

&lt;p&gt;The best practice to choose will depend of to know which how you will send and receive requests. For this, let’s see some high-level protocols.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communication Protocols
&lt;/h2&gt;

&lt;p&gt;Let's see some useful protocols that we can use in Distributed Architecture:&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/HTTPS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Client-Server communication&lt;/strong&gt;&lt;/em&gt;: allows to segregate tasks between client and server&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Stateless&lt;/strong&gt;&lt;/em&gt;: each request is independent&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/em&gt;: easy server replication&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RPC
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Transparent Integration&lt;/strong&gt;&lt;/em&gt;: call remote functions as local functions&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Network Abstraction&lt;/strong&gt;&lt;/em&gt;: you do not need to care about the subjacent networks&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Concurrency Manager&lt;/strong&gt;&lt;/em&gt;: allows control of transactions and distributed locks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MQ (Message Queue)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;As AMQP or MQTT&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Decoupling and Asynchronism&lt;/strong&gt;&lt;/em&gt;: A component can send a message without waiting for your processing&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Fault Tolerance&lt;/strong&gt;&lt;/em&gt;: Ensure message delivery even if systems are temporarily unavailable&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Load Balance&lt;/strong&gt;&lt;/em&gt;: Allows to distribute messages in many server instances&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;Integration of Heterogeneous Systems&lt;/strong&gt;&lt;/em&gt;: Programming language agnostic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s see how we can use all these things together in an architecture/code design&lt;/p&gt;

&lt;h2&gt;
  
  
  Architectures/Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Client-Server
&lt;/h3&gt;

&lt;p&gt;It is when you divide the application into two, client and server. The client is the part that is responsible for interacting with the end user, and the server provides all the client requests. The client can be software in a mobile phone or web application, and the server can be a dedicated machine. We need to pay attention to a single point, which every request on the server needs a response, so the clients wait for the server to process the request.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Service-Oriented Architecture
&lt;/h3&gt;

&lt;p&gt;A way to goal organize a system with interconnected services. Service in this context is autonomous, independent, and exposed. Following the Distributed System, we can distribute different tasks to different services.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Microservices
&lt;/h3&gt;

&lt;p&gt;This pattern almost follows the same way as SOA, but the difference is how the Consumer Layer uses the services. In this case, we do not need the ESB, the services are so independent that the Consumer Layer uses it directly and their infrastructure is just for itself.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Event-Driven Architecture
&lt;/h3&gt;

&lt;p&gt;We can do this pattern in different scenarios, from Monolithic to Microservice. The idea is to use the MQ protocol to do async communication, in which we can use the load balance strategy and redirect all the charges to the infrastructure, like Message Brokers. This is useful for distributing the same task process to different server instances.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Actor Models
&lt;/h3&gt;

&lt;p&gt;This pattern is based on Actors, in which each actor is an independent unit and your interactions are by messages. This kind of architecture works with a stateful strategy, and for this is very performative.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;We need to recognize this way brings us some benefits, like resilience, scalability, and performance. But we need to see the complexity and challenges that exist, too, like architectural decisions, concurrency controls, and protocol management. For this, we can look at the CAP Theorem, which may help us choose between consistency, availability, and fault tolerance.&lt;/p&gt;

&lt;p&gt;The comprehension of these trade-offs helps us to decide the best way to follow and the best alignment between the tech team and product team.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: This article brings us an overview of the distributed system, we did not go deep into any concepts. For this, we require a deeper study.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Abbreviations / Significates
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPOF&lt;/strong&gt;: Single Point Of Failure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;POD&lt;/strong&gt;: Kubernetes abstraction that represents a group of one or more application containers, and some shared resources for those containers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VM&lt;/strong&gt;: Virtual Machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RPC&lt;/strong&gt;: Remote Procedure Call&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AMQP&lt;/strong&gt;: Advanced Message Queuing Protocol&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MQTT&lt;/strong&gt;: Message Queuing Telemetry Transport&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ESB&lt;/strong&gt;: Enterprise Service Bus&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@tanstorm/cap%C3%ADtulo-10-arquitetura-distribu%C3%ADda-arquitetura-descentralizada-e-redes-sociais-federadas-23c27c07ae6"&gt;Chapter 10: Distributed Architecture, Decentralized Architecture, and Federated Social Networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/microservices/microservices-architecture/distributed-architecture"&gt;Distributed Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://controlf5.com.br/programacao-distribuida-o-que-e-e-onde-e-usada/#:~:text=A%20Programa%C3%A7%C3%A3o%20Distribu%C3%ADda%20%C3%A9%20quando,rede%20de%20internet%20ou%20intranet"&gt;DISTRIBUTED PROGRAMMING: WHAT IT IS AND WHERE IT IS USED&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.inf.ufsc.br/~frank.siqueira/INE5645/4.%20Programacao%20Distribuida.pdf"&gt;4. Distributed Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cult.honeypot.io/reads/optimistic-vs-pessimistic-concurrency/"&gt;Optimistic vs Pessimistic Concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://radar.oreilly.com/2015/02/variations-in-event-driven-architecture.html"&gt;Variations in Event-Driven Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://microservices.io/"&gt;Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.3pillarglobal.com/insights/event-driven-architecture-topologies-broker-and-mediator/"&gt;Event-Driven Architecture Topologies Broker and Mediator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>distributedsystems</category>
      <category>programming</category>
      <category>development</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Aplicando Conceitos TDD em .NET</title>
      <dc:creator>Alex Alves</dc:creator>
      <pubDate>Thu, 04 Jan 2024 18:17:26 +0000</pubDate>
      <link>https://dev.to/uaiboratech/aplicando-conceitos-tdd-em-net-399a</link>
      <guid>https://dev.to/uaiboratech/aplicando-conceitos-tdd-em-net-399a</guid>
      <description>&lt;p&gt;O Test-Driven Development é uma prática onde desenvolve-se um projeto ou parte dele pensando, primeiramente, em testes. O próprio nome traduzido já é uma auto-explicação, Desenvolvimento Dirigido por Testes. Tal prática tornou-se popular e, consequentemente, muito utilizada devido a garantia de funcionamento e qualidade de itens de desenvolvimento entregues.&lt;/p&gt;

&lt;p&gt;Neste contexto, surge algumas perguntas, tais como:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qual a vantagem em desenvolver assim?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maior cobertura de testes no código&lt;/li&gt;
&lt;li&gt;Garantia que os requisitos solicitados funcionem&lt;/li&gt;
&lt;li&gt;Qualidade do código (onde o próprio código de testes traz informações sobre a qualidade do código produzido)&lt;/li&gt;
&lt;li&gt;Garantia da entrega de um produto com maior qualidade&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Qual a diferença entre utilizar TDD e criar os testes após o desenvolvimento?&lt;/strong&gt;&lt;br&gt;
A qualidade final de um código está com base nos testes criados. A diferença entre a maneira que cria-se os testes está no retorno de feedback do teste para o desenvolvedor.&lt;/p&gt;

&lt;p&gt;Se um programador começa a criar os testes primeiro, ele recebe feedback constantemente, pois o mesmo consegue dividir seu trabalho em pequenas tarefas. Onde o mesmo consegue ter os seguintes passos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Escrever um teste&lt;/li&gt;
&lt;li&gt;Implementar um pedaço da funcionalidade&lt;/li&gt;
&lt;li&gt;Executar o teste&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A cada teste escrito ele recebe um feedback. E, com isso, fica fácil de alterar o código feito.&lt;/p&gt;

&lt;p&gt;Quando o programador desenvolve primeiro e depois, ao final, cria os testes, ele não recebeu nenhum feedback. E ao criar os testes, caso tenha que realizar alguma alteração, a mesma pode ser complexa e trabalhosa e levar um tempo maior para ser feita, custando cara.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isso irá diminuir minha produtividade?&lt;/strong&gt;&lt;br&gt;
Onde pratica-se o TDD, obviamente o desenvolvedor irá gastar um maior tempo criando testes, mas não significa ser menos ou mais produtivo.&lt;/p&gt;

&lt;p&gt;Tal tempo gasto, é gasto de maneira inteligente. Pois os testes criados, irão perdurar até o fim do projeto/código, ou seja, irá durar por muito tempo. E, além isso, podem ser executados a qualquer momento e quantas vezes for necessário, visando a garantia do código feito.&lt;/p&gt;

&lt;p&gt;Também, ao criar/pensar em testes primeiro, facilita as modificações no código que for preciso, como citado acima.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como funciona o TDD?&lt;/strong&gt;&lt;br&gt;
TDD é uma técnica de desenvolvimento baseado em um ciclo, independente da linguagem de programação, composto por passos que são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Criar um cenário de teste baseado em uma regra de negócio&lt;/li&gt;
&lt;li&gt;Criar o teste baseado no cenário&lt;/li&gt;
&lt;li&gt;Executar o teste criado (irá falhar)&lt;/li&gt;
&lt;li&gt;Escrever o código até que o teste apresente sucesso&lt;/li&gt;
&lt;li&gt;Refatorar o código desenvolvido&lt;/li&gt;
&lt;li&gt;Executar o teste novamente&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Basicamente, é o que está apresentado na imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7hlXb7VW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmrs5xgr72if3pxmmp19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7hlXb7VW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmrs5xgr72if3pxmmp19.png" alt="Image description" width="346" height="346"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🔧 Mão na massa!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Regra de negócio&lt;/strong&gt;&lt;br&gt;
Antes de tudo, é preciso ler e entender qual é a regra de negócio que será solicitada. Sendo assim, tem-se:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dado itens de produtos, é necessário permitir o cadastro de tais itens. Onde cada produto terá as seguintes informações com seus respectivos tipos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nome [string]&lt;/li&gt;
&lt;li&gt;Código do produto [string]&lt;/li&gt;
&lt;li&gt;Descrição [string]&lt;/li&gt;
&lt;li&gt;Valor de custo [decimal]&lt;/li&gt;
&lt;li&gt;Valor de venda [decimal]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deve-se considerar as seguintes regras, ao realizar o cadastro de algum item:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os campos obrigatórios serão: 'Nome', 'Código do produto' e 'Valor de custo'&lt;/li&gt;
&lt;li&gt;O campo 'Valor de custo' deve ser maior do que zero&lt;/li&gt;
&lt;li&gt;A quantidade de caracteres do campo 'Nome' deve ser inferior a 100&lt;/li&gt;
&lt;li&gt;A quantidade de caracteres do campo 'Descrição' deve ser inferior a 500&lt;/li&gt;
&lt;li&gt;O campo 'Código do produto' deverá conter, exatamente, 6 caracteres&lt;/li&gt;
&lt;li&gt;O 'Valor de venda' será calculado automaticamente, onde constituirá do 'Valor de custo' + 15% de seu valor&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Cenário de teste&lt;/strong&gt;&lt;br&gt;
Dado a regra de negócio acima, necessita-se criar os cenários de teste. No caso, cria-se apenas um como demonstrativo, sendo ele:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deve-se testar um produto válido, onde apresenta-se um item composto pelos seguintes dados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nome: Notebook Acer&lt;/li&gt;
&lt;li&gt;Código: 849071&lt;/li&gt;
&lt;li&gt;Valor de custo: R$ 1.843,25&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deve-se validar todos os campos, de acordo com as regras, onde o resultado deverá ser sucesso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Construção do teste&lt;/strong&gt;&lt;br&gt;
Com o cenário de teste já definido, pode-se criar os testes via código, como é exibido abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProdutoTest&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TestMethod&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;DataRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Notebook Acer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"849071"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1843.25&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SalvarProduto_ComDadosValidos_Sucesso&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//action&lt;/span&gt;
        &lt;span class="n"&gt;Produto&lt;/span&gt; &lt;span class="n"&gt;produto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Produto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;//assert&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNotNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Codigo&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValorCusto&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValorCusto&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Codigo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValorVenda&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;2119.7375&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analisando o código, nota-se o seguinte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Para que um produto exista é necessário informar o nome, código e valor de custo do mesmo. Com isso, tais campos são cobrados no construtor da classe e a mesma não deve permitir ser instanciada sem tais campos, atendendo a primeira regra de validação.&lt;/li&gt;
&lt;li&gt;É testado se o campo referente ao Valor de Custo é maior do que zero, atendendo a segunda regra de validação&lt;/li&gt;
&lt;li&gt;É testado se o campo referente ao nome tem o número de caracteres menor ou igual a 100, atendendo a terceira regra de validação&lt;/li&gt;
&lt;li&gt;É testado se o campo referente ao código do produto tem o número de caracteres igual, exatamente, a 6, atendendo a quinta regra&lt;/li&gt;
&lt;li&gt;É testado se o campo referente ao valor da venda é igual a 2119.7375, valor obtido pela fórmula descrita na regra de negócio, atendendo a sexta regra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Execução do teste&lt;/strong&gt;&lt;br&gt;
Após o teste já estar desenvolvido, pode-se executá-lo. Como ainda não tem-se nenhum código criado, o teste não será executado e irá dar erro de compilação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D1cVm2VT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8mxts5wz2sz6dgvg2ae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D1cVm2VT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8mxts5wz2sz6dgvg2ae.png" alt="Image description" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escrita do código&lt;/strong&gt;&lt;br&gt;
Após analisar o teste criado, deve-se desenvolver o código que irá atendê-lo, ou seja, criar a classe Produto com todos os atributos esperados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Produto&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Produto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Codigo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ValorCusto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Codigo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;ValorCusto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;ValorVenda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ValorCusto&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1.15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Refatoração do código escrito&lt;/strong&gt;&lt;br&gt;
Como o código desenvolvido está atendendo perfeitamente as regras de negócio, não será necessário refatorá-lo. Apenas se houver alguma mudança na própria regra.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execução novamente do teste&lt;/strong&gt;&lt;br&gt;
Por fim, ao executar o teste novamente, nota-se que o mesmo irá ter um resultado de sucesso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sbQQvz6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2im7bklufkt6b5whi4mu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sbQQvz6s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2im7bklufkt6b5whi4mu.png" alt="Image description" width="319" height="98"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Seguindo tais práticas, garante-se que o código desenvolvido sempre estará coberto por uma certa quantidade de testes. Onde, a cada alteração do código pode-se assegurar que o mesmo estará em funcionamento.&lt;/p&gt;

&lt;p&gt;É válido, também, considerar que os teste não são imutáveis. Pois as regras de negócio podem sofrer alterações.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://tdd.caelum.com.br/"&gt;http://tdd.caelum.com.br/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.devmedia.com.br/tdd-em-csharp-na-pratica-por-onde-o-projeto-deve-iniciar/28419"&gt;https://www.devmedia.com.br/tdd-em-csharp-na-pratica-por-onde-o-projeto-deve-iniciar/28419&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tableless.com.br/tdd-por-que-usar/"&gt;https://tableless.com.br/tdd-por-que-usar/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.eusoudev.com.br/tdd/"&gt;https://www.eusoudev.com.br/tdd/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>User Secrets in your .NET Project</title>
      <dc:creator>Alex Alves</dc:creator>
      <pubDate>Thu, 11 May 2023 21:07:42 +0000</pubDate>
      <link>https://dev.to/alexalvess/user-secrets-in-your-net-project-1766</link>
      <guid>https://dev.to/alexalvess/user-secrets-in-your-net-project-1766</guid>
      <description>&lt;p&gt;Genarally, we need to include some sensitive data in our appsettings.json file, like a connection string that content a username and password or a something kind of private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ConnectionStrings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"MongoDb"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mongodb://mongoadmin:secret@127.0.0.1:27017/aurora/?authSource=admin"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the exposure of these credentials is not safe and is not a good practice either. And, when a developer get your repository, maybe they need to do adjust your docker images or change the sensitive data/connection strings to attend the project.&lt;/p&gt;

&lt;p&gt;Let's see how can we solve this! 🤓&lt;/p&gt;

&lt;h2&gt;
  
  
  User Secrets
&lt;/h2&gt;

&lt;p&gt;This is a way that allows us to manage sensitive data for .NET on local development.&lt;/p&gt;

&lt;p&gt;So, to configure it in your project, you'll need something like below in your Startup/Program class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;WebApplication&lt;/span&gt; 
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureAppConfiguration&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;configurationBuilder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;configurationBuilder&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddUserSecrets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEnvironmentVariables&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to configure our secrets, right?&lt;br&gt;
First, let's open the startup project folder and, next open the terminal, and follow the commands below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To enable secret storage: &lt;br&gt;
&lt;code&gt;dotnet user-secrets init&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To add a secret: &lt;br&gt;
&lt;code&gt;dotnet user-secrets set "ConnectionStrings:MongoDb" "[YOUR CONNECTION]"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To add a secret in a list: &lt;br&gt;
&lt;code&gt;dotnet user-secrets set "PrivateKey[0]" "[YOUR KEY]"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;dotnet user-secrets set "PrivateKey[1]" "[YOUR KEY]"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To list the secrets:&lt;br&gt;
&lt;code&gt;dotnet user-secrets list&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To remove a secret:&lt;br&gt;
&lt;code&gt;dotnet user-secrets remove "ConnectionStrings:MongoDB"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;Never store passwords or other sensitive data in source code&lt;/li&gt;
&lt;li&gt;Production/Staging/Development should not be used for local test/development&lt;/li&gt;
&lt;li&gt;Sensitive data should not be deployed with the app&lt;/li&gt;
&lt;li&gt;You should store sensitive data in a protected environment/tool, like Azure Key Vault&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&amp;amp;tabs=windows"&gt;https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&amp;amp;tabs=windows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Message Types in Domain-Driven Design</title>
      <dc:creator>Alex Alves</dc:creator>
      <pubDate>Mon, 02 Jan 2023 12:19:51 +0000</pubDate>
      <link>https://dev.to/alexalvess/message-types-in-domain-driven-design-30bb</link>
      <guid>https://dev.to/alexalvess/message-types-in-domain-driven-design-30bb</guid>
      <description>&lt;p&gt;Before we start to talk about message types, let's talk about what is a message.&lt;/p&gt;

&lt;p&gt;A message is any intention of transmitting and/or processing information.&lt;/p&gt;

&lt;p&gt;A message, you can produce and consume from message brokers, message queues, log streams, or in-memory. But, the way to do it is not important, but the message intention, and information.&lt;/p&gt;

&lt;p&gt;Having that clear, let's identify what types of messages we have and how we can produce them! 🔥&lt;/p&gt;




&lt;h3&gt;
  
  
  Command Messages 🎯
&lt;/h3&gt;

&lt;p&gt;The goal of this message type it invokes a functionality in another application. Usually, it represents an action or intention to produce some effects in our system and is started for an external agent, like a user.&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%2Fwe68o4uf7wvtlzuvwsxp.jpg" 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%2Fwe68o4uf7wvtlzuvwsxp.jpg" alt="Image description" width="800" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important concept it's that this message has a specific recipient. And every command generates a side effect in Aggregate/Context&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Messages 🔊
&lt;/h3&gt;

&lt;p&gt;A difference between commands and events is that events do broadcast to anyone interested.&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%2F5j7s87hywdn2mf1ab8o2.jpg" 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%2F5j7s87hywdn2mf1ab8o2.jpg" alt="Image description" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domain Events&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we talk about DDD we talk about Domain/Business. So, when we triggered a command, this command generates a side effect in our System/Domain. This side effect we may call Domain Events, which represents business facts.&lt;/p&gt;

&lt;p&gt;Relevant points:&lt;br&gt;
    - Into a system, this event type may sensibilize other contexts or your own context/aggregate.&lt;br&gt;
    - Our Aggregate may be produce 1-N business facts/events.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integration Events&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generally, if other external agents were interested in something of any journey, it's common for the context to produce an event and contains all the necessary information. An example of it is when our system needs to produce events in a Data Lake. The Data Lake is out of our domain and tech.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Notification Events&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similar to Integration Events, the difference is the content. The Notification Event has just an ID, and your goal is to notify all interested that something happened. If the interested wants to get more information or trigger another process, doesn't matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query Messages 🔛
&lt;/h3&gt;

&lt;p&gt;When we need to recover some data from our system, we need to ask our application to recover it. We can use messages to do it. But, this is a little strange if we think about the async environment. So, for async applications, we can use the request-reply async pattern for this.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Messages is technology agnostic&lt;/li&gt;
&lt;li&gt;It's import to identify your message intention&lt;/li&gt;
&lt;li&gt;Your journey may be more fluid and clear&lt;/li&gt;
&lt;li&gt;If you decide to use a Message Broker, Queue, or Log Stream, it's important to direct each message to your specific channel, liek:

&lt;ul&gt;
&lt;li&gt;Message Brokers is an excellent tool for Commands and Domain Events&lt;/li&gt;
&lt;li&gt;Log Stream is an excellent tool for Integration Events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Request-Reply Async pattern is a good idea for ascyn environment&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.g2.com/articles/message-broker" rel="noopener noreferrer"&gt;https://www.g2.com/articles/message-broker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AntonioFalcaoJr/EDA.CleanArch.DDD.CQRS.EventSourcing" rel="noopener noreferrer"&gt;https://github.com/AntonioFalcaoJr/EDA.CleanArch.DDD.CQRS.EventSourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.enterpriseintegrationpatterns.com/" rel="noopener noreferrer"&gt;https://www.enterpriseintegrationpatterns.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codeopinion.com/do-you-want-to-use-kafka-or-do-you-need-a-queue/" rel="noopener noreferrer"&gt;https://codeopinion.com/do-you-want-to-use-kafka-or-do-you-need-a-queue/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/patterns/async-request-reply" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/azure/architecture/patterns/async-request-reply&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jokes</category>
    </item>
    <item>
      <title>Modeling your Domain with Event Storming workshop</title>
      <dc:creator>Alex Alves</dc:creator>
      <pubDate>Thu, 17 Nov 2022 20:43:09 +0000</pubDate>
      <link>https://dev.to/alexalvess/modeling-your-domain-with-event-storming-workshop-3dg9</link>
      <guid>https://dev.to/alexalvess/modeling-your-domain-with-event-storming-workshop-3dg9</guid>
      <description>&lt;p&gt;Event Storming is a technique that helps us to see our business from another optical. Well, I want to say that Event Storming shows us a map that contains: product intents, their comportments, and how the interactions occur... all of this in our software.&lt;/p&gt;

&lt;p&gt;So, I think you understand a little, right? Don't worry, we'll talk more about it in this article.&lt;/p&gt;

&lt;p&gt;Continuing... why do I talk about Event Storming? First, because I believe that the best way to build and model a software/product is by following the DDD (Domain-Driven Design) philosophy; and second, because I think that DDD and Event Storming fit perfectly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's Start!
&lt;/h2&gt;

&lt;p&gt;In a few words, Event Storming helps us to map the actions that occur in our software, including which side effects these actions produce. And, consequently, these side effects may trigger other actions. So, we'll build a flow, that helps us to see the boundaries of business intentions, what kind of intentions we have, and more.&lt;/p&gt;

&lt;p&gt;The image below is an example of Event Storming output:&lt;br&gt;
&lt;a href="https://media.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%2Ftbxj9uo2o15vipgsi0dj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftbxj9uo2o15vipgsi0dj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's explain this image:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🟡 Yellow cards:&lt;br&gt;
To start a flow/journey in our system we need some sensibilization, which is triggered by some users or other external systems. This sensibilization occurs externally. So, to represent it we use this card type named "Actors".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔵 Blue cards:&lt;br&gt;
When the actor uses our system he triggers some actions, like making a login, or buying a shirt in an e-commerce system. So, to represent this comportment, we use this card type named "Commands".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;👛Light Pink or Light Yellow cards:&lt;br&gt;
When actions/commands are triggered, these commands will enter our system/domain, causing some sensibilization. To represent this behavior/domain we use this card type and we named it "System" or "Aggregate".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🟠 Orange cards:&lt;br&gt;
Pause for this card!⚠️ As I said before, the commands will enter our system, right? So, when this happens, these actions will generate some side effects which are the most important thing that we need to map, because this show us that our system did something, something changed... So, when something (command) happens, our system runs some comportment, i.e. it execute a specific situation that exists in our business rules, our domain, and then a side effect will be generated. So, this type of card represent these side effects, and we name it "Events".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🟣 Purple cards:&lt;br&gt;
After these events occurred, they may trigger other specific commands. For it, we have some rules to decide it. So, these rules are represented by this card named "Policy".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🟢 Green cards:&lt;br&gt;
Beyond policy, after the events occurred, they may sensibilize a UI either. So, something happened and whoever started the journey may know what happened, e.g. see some data modified. To represent it, we use this card named "View", "Projection" or "Read Model".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔴 Pink/red cards:&lt;br&gt;
When we have doubts about some behaviors in our journey, we can pin an alert flag and postpone them. To represent it we use the card type named "Hotspot".It's important to solve these doubts at some point.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it, now we know more about Event Storming. But running an Event Storming session may have its difficulties like: not all participants will be kept engaged, sometimes may be boring, not everyone will know what they want from the product... and, explaining how Event Storming works may be confusing at the beginning and achieving this flow draw may be complex and difficult, but it's worth it! Let's talk about the workshop!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Workshop
&lt;/h2&gt;

&lt;p&gt;Exists many other techniques to do this workshop, but in this particular session, I'm going to talk step-by-step about an experience that works for me.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instead of running it with many people, from different areas, try to make a short group with people of the same area, including stakeholder, tech people, and managers.&lt;/li&gt;
&lt;li&gt;When you gather this short group, do an overview about the Event Storming, show the goals, the advantages, and the difficulties that may occur .&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From here, I think that we have a key to running it successfully:&lt;/p&gt;

&lt;p&gt;3.1. Instead of trying to start to draw the flow, propose to your group to brainstorm the commands/actions that may occur in the system/product. For non-technical people is easier thinking about the actions, as many of they start from a user and tend not to be a technical biased, than about the flow itself. Below you can see an example:&lt;br&gt;
&lt;a href="https://media.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%2Fvveaxdr55fp537k7g7qy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvveaxdr55fp537k7g7qy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3.2. After you have mapped your commands, you can order them chronological. This will help you to see where would start and end the flow:&lt;br&gt;
&lt;a href="https://media.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%2Fbqnbxjytqw3q5oc5kfat.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbqnbxjytqw3q5oc5kfat.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Note that, in this example after we ordered the commands, we have two paths. It means that looks like we can have two different flows/journeys in this case (although we thought that it was just one).&lt;/p&gt;

&lt;p&gt;3.3. Finally, we can adjust these commands and use all other  Event Storming cards type to fill the flow. Take this this moment to explain more about the Event Storming, specially the cards meaning and importance, and to envolve more the group to help you to build the flow:&lt;br&gt;
&lt;a href="https://media.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%2Foebju79b1zez8t7lbgla.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Foebju79b1zez8t7lbgla.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Look that we have two different contexts. This happens because after we mapped the commands, we identified two flows. It's a strong signal that may be different things, but it's not a sure think. Only after discussing it in the Event Storming session we agreed that made more sense segregated into two contexts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, that's how we can map our journeys!&lt;/p&gt;

&lt;p&gt;PS: This Event Storming is a reference to the &lt;a href="https://github.com/alexalvess/aurora-api-project" rel="noopener noreferrer"&gt;Aurora Project&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Domain-Driven Design &amp;amp; Event Storming
&lt;/h2&gt;

&lt;p&gt;Why is this a perfect match?&lt;/p&gt;

&lt;p&gt;DDD shows us how we can build better products, for that we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubiquitous language: is a unique language to enable developers, stakeholders and managers understand each other in prol to find the product actions. The Event Storming cards helps this understanding.&lt;/li&gt;
&lt;li&gt;Boundaries: is how we separate contexts. Note that when finished the workshop, we can see two different contexts, which show us what your boundary is.&lt;/li&gt;
&lt;li&gt;Context Map: we have all the context mapped and how they communicate with others.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Event Storming is an excellent tool to help us to get a better look at our product and what it does. Additionally, we can use this generated document to build our solution architecture, and how we can transform each context in a project/code. In my opinion, it increases our chance of creating something evolving, and easy to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challanges / Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Think about an architecture to attend the Event Storming&lt;/li&gt;
&lt;li&gt;Segregate our domain to attend the contexts mapped&lt;/li&gt;
&lt;li&gt;Transform all journeys in code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, for enterprises... think about how the squad can work together in this environment. The book "Team Topologies" may help us.&lt;/p&gt;




&lt;h2&gt;
  
  
  Acknowledgment
&lt;/h2&gt;

&lt;p&gt;None of that would be possible without the incentive, help and teachings of &lt;a href="https://github.com/AntonioFalcaoJr" rel="noopener noreferrer"&gt;Antonio Falcão&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eventstorming.com/book/" rel="noopener noreferrer"&gt;https://www.eventstorming.com/book/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AntonioFalcaoJr/EDA.CleanArch.DDD.CQRS.EventSourcing" rel="noopener noreferrer"&gt;https://github.com/AntonioFalcaoJr/EDA.CleanArch.DDD.CQRS.EventSourcing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://techbeacon.com/app-dev-testing/introduction-event-storming-easy-way-achieve-domain-driven-design" rel="noopener noreferrer"&gt;https://techbeacon.com/app-dev-testing/introduction-event-storming-easy-way-achieve-domain-driven-design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.lucidchart.com/blog/ddd-event-storming" rel="noopener noreferrer"&gt;https://www.lucidchart.com/blog/ddd-event-storming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>ddd</category>
      <category>eventdriven</category>
      <category>eventstorming</category>
    </item>
    <item>
      <title>Getting started with .NET Core API, MongoDB, and Transactions</title>
      <dc:creator>Alex Alves</dc:creator>
      <pubDate>Sat, 20 Nov 2021 22:46:09 +0000</pubDate>
      <link>https://dev.to/alexalvess/getting-started-with-net-core-api-mongodb-and-transactions-c44</link>
      <guid>https://dev.to/alexalvess/getting-started-with-net-core-api-mongodb-and-transactions-c44</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2F4ydrquufomkygmhj0ufi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4ydrquufomkygmhj0ufi.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MongoDB is a kind of NoSQL database. NoSQL is a document-oriented database that is organized as a JSON. Some points about MongoDB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; It stores a majority of data in RAM, so the query performance is much better here than in a relational database. But it requires more RAM and precise indexes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity:&lt;/strong&gt; Some users consider the query syntax is simpler here than in relational databases. The installation, configuration, and execution are simple and quick to do. And the learning curve is shorter than in the others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; It’s dynamic because it doesn’t have a predefined schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; It’s dynamic because it doesn’t have a predefined schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction:&lt;/strong&gt; v3.6 and beyond allow using the transaction concept. And v4.0 and beyond allow using the multi-document transaction concept.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you know a little more about MongoDB, let’s go to our goal! This article proposes to teach you how you can build a .NET Core API connecting with MongoDB and use the Transactions with Dependency Injection.&lt;/p&gt;

&lt;h2&gt;
  
  
  #ShowMeTheCode!
&lt;/h2&gt;

&lt;p&gt;For this example, don’t consider the structure and the architecture, it was built in this way just because I think that it’s easier to explain. So, I won’t explain the layers, folders, and other things in detail, except those needed by the use of MongoDB and the transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  The project
&lt;/h3&gt;

&lt;p&gt;In this case, I used the Visual Studio 2019, Community version. So, with the VS installed, we select the “ASP.NET Core Web Application” option and select the API type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fl2raj9oas0xfc1awyjr8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fl2raj9oas0xfc1awyjr8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8gx42vm1w99eeuu6harf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8gx42vm1w99eeuu6harf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  About the base structure
&lt;/h4&gt;

&lt;p&gt;After creating the project, we create five folders like below:&lt;br&gt;
&lt;a href="https://media.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%2Ftixpt2b2bvecbl1obfhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftixpt2b2bvecbl1obfhv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controllers: responsible to answer the requests&lt;/li&gt;
&lt;li&gt;Entities: Domain classes&lt;/li&gt;
&lt;li&gt;Interfaces: like contracts, we’ll use it to do the DI and IoC&lt;/li&gt;
&lt;li&gt;Models: Classes that we’ll use to receive and return data on controllers&lt;/li&gt;
&lt;li&gt;Repositories: Classes with methods that contain the implementation of MongoDB operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll focus on just Controllers and Repositories folders and the Startup class. If you want to see the complete code, wait for the end of this article.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing and configuring MongoDB
&lt;/h3&gt;

&lt;p&gt;Now, we need to install the more important package for our project, that is the MongoDB.Driver.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvffqpyu9i3kdm4tfm4nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvffqpyu9i3kdm4tfm4nk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installed, we need to modify the Startup class, on the ConfigureServices method, specifically.&lt;/p&gt;

&lt;p&gt;Let’s analyze this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMongoClient&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EscapeDataString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mongodb+srv://{0}:{1}@{2}/test?retryWrites=true&amp;amp;w=majority"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMongoClient&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;StartSession&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The ConfigureServices method is where we do our IoC. So, the first statement is where we make the MongoDB connection. Pay attention in this step because we make a Singleton, we do this because the MongoClient instance, in MongoDB, is already a pool connection, so if you don’t use a Singleton, a new pool connection will always be created.&lt;/p&gt;

&lt;p&gt;And the second statement is where we declare the IoC, which we’ll use to start a session of the MongoDB Transaction. Notice that, in this case, we make a Scoped, because the transaction life cycle will be equal to the request life cycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a base repository
&lt;/h3&gt;

&lt;p&gt;So now, let’s make a base repository that we will use whenever we want to do some operations. First, the base repository class will receive a Generics  to identify the entity in our code that represents a collection in the database, like below:&lt;/p&gt;

&lt;p&gt;After creating the class, let’s go to declare some attributes that will be important to us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRepositoryBase&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseEntity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// some code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have four attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRepositoryBase&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseEntity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DATABASE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"poc_dotnet_mongodb"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IMongoClient&lt;/span&gt; &lt;span class="n"&gt;_mongoClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IClientSessionHandle&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_collection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;DATABASE: it’s the Constant that represents the name of our database.&lt;/li&gt;
&lt;li&gt;_mongoClient: it’s the client interface to MongoDB. Using it we do some operations on the database.&lt;/li&gt;
&lt;li&gt;_clientSessionHandle: it’s the interface handle for a client session. So, if you start a transaction, you should pass the handle when you do some operation.&lt;/li&gt;
&lt;li&gt;_collection: it’s the name of the collection used by the Generic class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these attributes will receive a value on a class constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRepositoryBase&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseEntity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DATABASE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"poc_dotnet_mongodb"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IMongoClient&lt;/span&gt; &lt;span class="n"&gt;_mongoClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IClientSessionHandle&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_collection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IMongoClient&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IClientSessionHandle&lt;/span&gt; &lt;span class="n"&gt;clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_mongoClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;_mongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATABASE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ListCollectionNames&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;_mongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATABASE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;CreateCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the constructor parameters. We receive these parameters by dependency injection. We get the values of parameters and we assign them to the attributes that we created.&lt;/p&gt;

&lt;p&gt;Another very important thing is the code below of the assignments. If you work with transactions, on MongoDB, and work with a multi-document transaction, we need to create the collection first of all. And for it, we verify if the collection exists in our database and, if not, we create it. If we try to create a collection that already exists, the flow will break and throw an exception.&lt;/p&gt;

&lt;p&gt;Now, we will do an important code too, specifically a virtual property that we use to facilitate to do some operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRepositoryBase&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseEntity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...some attributes and the constructor...&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;IMongoCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;_mongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATABASE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;GetCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_collection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// ...some other codes...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the _mongoClient attribute, we retrieve the database and, from the _collection attribute, we retrieve the collection and associate it with the Generic class.&lt;/p&gt;

&lt;p&gt;Finally, we build some base operations to change the data in the database like Insert, Update, and Delete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IRepositoryBase&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseEntity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;InsertAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;UpdateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;GetProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Builders&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReplaceOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;DeleteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeleteOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some important things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have to pass the _clientSessionHandle for all the methods that do, in fact, the operation, like the InsertOneAsync method.&lt;/li&gt;
&lt;li&gt;To do an Update operation, we build a Lambda Expression, using the ID property. And then, we use a Reflection to retrieve the ID value and we make the filter that will use to do, in fact, the operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example of a specifical repository
&lt;/h3&gt;

&lt;p&gt;Now I show you how we can use the Base Repository to do some other specifically repository. In this case, we’ll build an AuthorRepository.&lt;/p&gt;

&lt;p&gt;First, we build the class with the inheritances and the constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthorRepository&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;IRepositoryAuthor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AuthorRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;IMongoClient&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;IClientSessionHandle&lt;/span&gt; &lt;span class="n"&gt;clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// some code...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we inherit the BaseRepository class, we force it to make a constructor as shown. Look at how we pass the collection name using a string “author”.&lt;/p&gt;

&lt;p&gt;Finally, we build some other MongoDB operations, here we build only specific query operations to get data. It happens because we can get specific data in each moment, but the operations that change the database data (like insert, update, delete) will be always the same in this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthorRepository&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;IRepositoryAuthor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... constructor code&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAuthorByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Builders&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAuthorsAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsQueryable&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetBooksAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;authorId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Builders&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;authorId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Books&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAuthorsByNameAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Builders&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, I show you some query operations examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can recover one author searching by id.&lt;/li&gt;
&lt;li&gt;We can recover all authors.&lt;/li&gt;
&lt;li&gt;We can recover all books of a specific author, searching by author’s id, using the Project method.&lt;/li&gt;
&lt;li&gt;We can recover some authors searching by name.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Business rules examples with transactions
&lt;/h3&gt;

&lt;p&gt;Let’s use these repositories to do some business rules and use, in fact, the transactions! For this, we’ll make all business rules in the classes located in the Controller folder.&lt;/p&gt;

&lt;p&gt;So, we build a class called BusinessController, like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BusinessController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IRepositoryUser&lt;/span&gt; &lt;span class="n"&gt;_repositoryUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IRepositoryAuthor&lt;/span&gt; &lt;span class="n"&gt;_repositoryAuthor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IClientSessionHandle&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BusinessController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;IRepositoryUser&lt;/span&gt; &lt;span class="n"&gt;repositoryUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;IRepositoryAuthor&lt;/span&gt; &lt;span class="n"&gt;repositoryAuthor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;IClientSessionHandle&lt;/span&gt; &lt;span class="n"&gt;clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_repositoryUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_repositoryAuthor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repositoryUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repositoryAuthor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ll don’t talk about the Annotations and the inheritances class, because it’s specific for the API. So, look that we use the repositories that we created before and a session _clientSessionHandle that we’ll use to make the transactions. All these attributes we’ll receive on the constructor parameters by dependency injection.&lt;/p&gt;

&lt;p&gt;So now, let’s show how we can use a transaction, in fact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BusinessController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... some code&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;InsertUser&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CreateUserModel&lt;/span&gt; &lt;span class="n"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repositoryUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CommitTransactionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AbortTransactionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ... some code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, it’s a POST method, which means that we want to insert a new record on the database. In the method beginning, we need to start a transaction (line 11), then we can make our business rules and, if there is nothing wrong, we can Commit all changes we did on the database. But if something break, an exception will be thrown and the flow will begin on the Catch statement, thereby, we’ll abort all the transaction and nothing in the database will be changed.&lt;/p&gt;

&lt;p&gt;Below you can look another example using multi-document transactions. Where we use more than one operation on the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BusinessController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... some code&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"authorAndUser"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;InsertAuthorAndUser&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;CreateAuthorAndUserModel&lt;/span&gt; &lt;span class="n"&gt;authorAndUserModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartTransaction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authorAndUserModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthorModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;authorAndUserModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthorModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authorAndUserModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;authorAndUserModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repositoryAuthor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repositoryUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CommitTransactionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_clientSessionHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AbortTransactionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ... some code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic is the same as the code shown before.&lt;/p&gt;

&lt;p&gt;I expect that you liked this article! If yes, give a like to it. If you have any doubt or any questions comment below.&lt;br&gt;
You can find the complete code &lt;a href="https://github.com/alexalvess/poc-dotnet-mongodb" rel="noopener noreferrer"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fafod24mj02tn3rw5jk9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fafod24mj02tn3rw5jk9k.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/selleo/the-pros-and-cons-of-using-mongodb-8e7601857a8e" rel="noopener noreferrer"&gt;https://medium.com/selleo/the-pros-and-cons-of-using-mongodb-8e7601857a8e&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.virtual-dba.com/pros-and-cons-of-mongodb/" rel="noopener noreferrer"&gt;https://www.virtual-dba.com/pros-and-cons-of-mongodb/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.mongodb.com/manual/reference/method/Session/" rel="noopener noreferrer"&gt;https://docs.mongodb.com/manual/reference/method/Session/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>mongodb</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
