<?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: amr swalha</title>
    <description>The latest articles on DEV Community by amr swalha (@amr_swalha_82613bccd3419d).</description>
    <link>https://dev.to/amr_swalha_82613bccd3419d</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%2F2116900%2Febd04c31-a21e-415c-97b2-822359097bd8.jpg</url>
      <title>DEV Community: amr swalha</title>
      <link>https://dev.to/amr_swalha_82613bccd3419d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amr_swalha_82613bccd3419d"/>
    <language>en</language>
    <item>
      <title>Theory of Abstraction</title>
      <dc:creator>amr swalha</dc:creator>
      <pubDate>Sun, 29 Jun 2025 14:20:04 +0000</pubDate>
      <link>https://dev.to/amr_swalha_82613bccd3419d/theory-of-abstraction-1ki6</link>
      <guid>https://dev.to/amr_swalha_82613bccd3419d/theory-of-abstraction-1ki6</guid>
      <description>&lt;p&gt;I’ve been building software for years, what I love about it and sometimes hate is that everything keeps changing so fast that a framework can become obsolete and deprecated within two years or even less.&lt;/p&gt;

&lt;p&gt;What happens is that a lot of projects don’t want to reinvent the wheel, which makes a lot of sense. They use external libraries and frameworks. These external dependencies are strongly coupled inside the project.&lt;/p&gt;

&lt;p&gt;Which makes it hard and sometimes impossible to replace or update. And guess what, these dependencies introduce vulnerabilities and security issues, or sometimes they use an outdated approach and do not follow the latest trends, which makes them no longer optimal to use.&lt;/p&gt;

&lt;p&gt;So the more you rely on external dependencies, the more you are likely to have to refactor many parts of your application, or even worse, replace the entire thing. This can be very costly, and not only that, since there is a pandemic of low-quality code and documentation, the process of modernizing your app will be very difficult and hard to do.&lt;/p&gt;

&lt;p&gt;So, Mr. Amr, what will we do? How can we do software development and develop software that can run forever? When the aliens come down and they try to run it, it will be as easy as calling an npm script.&lt;/p&gt;

&lt;p&gt;There is no simple answer, but there is an approach that I'm adapting currently that we think can mitigate these issues. Although,&lt;br&gt;
Eventually, you will reach a point where you will have to refactor the entire thing; this will make the process easier and even a breeze. &lt;/p&gt;

&lt;p&gt;The Theory of Abstraction State:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The more Abstraction you introduce inside your code, the more likely you are to replace and update dependencies inside your code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No easy way to do this, and the level of abstraction can vary a lot between projects. For example, if you are using Angular and you have one of the well-known&lt;br&gt;
packages such as &lt;a href="https://primeng.org/" rel="noopener noreferrer"&gt;PrimeNG&lt;/a&gt;, where you will use a modal. You can use it directly from the library, but what will you do if you want to update or even replace the entire library? &lt;/p&gt;

&lt;p&gt;Using any external dependencies as a very tightly coupled unit inside the code will make it a dependency hard to replace or change. I'm sure the good folks at PrimeNG will maintain the computability as much as possible. But, since technology changes at an insane rate, they have to do a cut-off support at some point, like any project that wants to stay relevant.&lt;/p&gt;

&lt;p&gt;I worked on a very large project that used Angular, and when I wanted to update it the version I hit a wall with a package that was used all over the place. And its job was only to display a Model! So, it was difficult to update. &lt;/p&gt;

&lt;p&gt;It was very difficult to locate its usage and where to update. Since then, I thought, what if I introduced just a small component that holds any modal library, and instead used it? Then my update was way simpler.&lt;/p&gt;

&lt;p&gt;Also, many open-source packages start with a free license and then switch their license, which can lead to many implications. By adding an abstraction layer (I know it's a difficult task) to all or at least the most critical package(s), it can lower the update and change time.&lt;/p&gt;

&lt;p&gt;Remember that the framework version is just a number, code never rusts and will not be a big issue to use even .NET 4.5 or Angular 7 to this day, unless there is a critical security issue or you can no longer run the application.&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://amr-blog.netlify.app/blog/theory-of-abstraction/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>abstraction</category>
      <category>architecture</category>
    </item>
    <item>
      <title>.NET Clean Architecture, Yet Another!</title>
      <dc:creator>amr swalha</dc:creator>
      <pubDate>Wed, 14 May 2025 10:35:47 +0000</pubDate>
      <link>https://dev.to/amr_swalha_82613bccd3419d/net-clean-architecture-yet-another-j9l</link>
      <guid>https://dev.to/amr_swalha_82613bccd3419d/net-clean-architecture-yet-another-j9l</guid>
      <description>&lt;p&gt;As you for sure know, there is a lot of .NET Clean Architecture projects, we try to provide a much easier one to use and one that can help developer provide much better results. So, we released &lt;a href="https://github.com/advanced-software-solutions/.net-clean-archticture" rel="noopener noreferrer"&gt;.NET Clean Architecture&lt;/a&gt; that we worked on for years and used it in multiple projects to help other fellow software developers build better .NET applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;While working at some company, I saw an architecture that layered the application into 4 parts: Core for entities, Infra for general operations, Business for the implementation and the API layer to expose them all.&lt;/p&gt;

&lt;p&gt;When looking at them, they really provided a good way to separate the different layers and make the work more reusable. But there was a big problem of boilerplate code for the basic operations.&lt;br&gt;
You had to have on each class GetById and you had to write them for each one, so this was way too boring and redundant for me as a guy who had installed many extensions just to save a few clicks ;)&lt;/p&gt;

&lt;p&gt;So, I wanted to make a better solution where you don't have this many codes to write each time and all the basic cruds are already there. So, after some time of trying and testing, I started this project as an internal tool for Advanced Software Solutions and used it in many projects. Now, reached V2.0 I want it to have more exposure and have more people feedback. Also, it was battle tested with a small company, and they liked it a lot so I want more people to take advantage of this.&lt;/p&gt;
&lt;h3&gt;
  
  
  V1.0
&lt;/h3&gt;

&lt;p&gt;In this version, I had the four layers, Core Operation Business and the API layer. This version was a good start as it shown the ability of the architecture to minimize the need to create any GET operation unless it was very custom, due to the usage of OData. Just add your entity and map it to EF, add a service and an api controller and magic you have all the CRUDs you need created for you. If you want a custom method, you can add it freely to the API or the service.&lt;/p&gt;

&lt;p&gt;The feedback was really good, and the usage of this method was really helpful for the developers. But we got feedback that the developers had each time to add a new entity the need to add a service and an API controller. Which became very redundant task in case the application grows bigger. Also, most of the time they just needed the basic CRUD and rarely edited the service or the controller.&lt;/p&gt;
&lt;h3&gt;
  
  
  V2.0+ (Current Release)
&lt;/h3&gt;

&lt;p&gt;Taking advice from the first release, I looked at the architecture again and decided the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instead of using a service for each entity, and most of the time you don't need a custom code, the Business layer is optional for each entity. If you need more custom code or business logic, you implement an Actor using Akka and then create a partial class for the API controller to use it.&lt;/li&gt;
&lt;li&gt;The usage of .NET Source Generator to lower the amount of boilerplate code. Just add your entity and map it to EF and you are all set! The Source Generators will generate the API controller for you, and you will have all the CRUD ready with OData as well.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;First please go to &lt;a href="https://github.com/advanced-software-solutions/.net-clean-archticture" rel="noopener noreferrer"&gt;.NET Clean Architecture&lt;/a&gt; and then download the project. &lt;/p&gt;

&lt;p&gt;Afterward, you can run the project directly from VS 2022 or just use .NET run cli command (dotnet run) and make sure you install the latest SDK (.NET 9 at the time of writing). &lt;/p&gt;

&lt;p&gt;After running the application you will be presented by Scalar&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%2Fsp2ehwgwdv8elkrea8jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsp2ehwgwdv8elkrea8jj.png" alt="Project After Running" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;In the appsettings.Development.json, you can specify the configuration for the application. The "CleanAppConfiguration" section contains the configuration needed for the application to function correctly. Let's take a look at the section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"CleanAppConfiguration": {
    "InMemoryCaching": {
      "Enabled": true,
      "Provider": "InMemory",
      "Configs": {
        "Host": "localhost",
        "Port": "11211"
      }
    },
    "Auth": {
      "Authority": "CleanAPI",
      "Audience": "CleanAPI",
      "ValidAudiences": [
        "CleanAPI"
      ],
      "ValidIssuers": [
        "CleanAPI"
      ],
      "Key": "d18bf0b49d5c2679e2250246779570f7a5e79f23"
    },
    "Datastore": {
      "ConnectionString": "Data Source=.;Database=CleanDB;Integrated Security=True;Persist Security Info=False;Pooling=False;Multiple Active Result Sets=False;Connect Timeout=60;Encrypt=False;Trust Server Certificate=True;Command Timeout=0",
      "Provider": "SQLite"
    },
    "ResponseCache": {
      "Enabled": true,
      "Duration": 30,
      "VaryByHeaders": ["Authorization"]
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;InMemoryCaching

&lt;ul&gt;
&lt;li&gt;This to configure the caching for the api and you can enable it or turn it off. You can choose the InMemory or Memcached.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Auth

&lt;ul&gt;
&lt;li&gt;To configure the authorization on the API, make sure to change the key and the relevant information.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Datastore

&lt;ul&gt;
&lt;li&gt;Where you can configure the datastore, either in memory, SQLite, SQL Server or Postgres. Note that the connection string is required for the SQL server and Postgres.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Note the &lt;strong&gt;ResponseCache&lt;/strong&gt; section is under development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an Entity
&lt;/h2&gt;

&lt;p&gt;To expose an entity, simply add it inside the CleanBase project inside the Entity folder. After that, make it inherit the &lt;strong&gt;EntityRoot&lt;/strong&gt; class. And you are done! The source generator will generate the API controller for you and hookup the OData to it, so you are good to go!&lt;/p&gt;

&lt;p&gt;You can see the generated code for the controller by going to CleanAPI -&amp;gt; Analyzers -&amp;gt; CleanAPIGenerator -&amp;gt; Expand the generator as the image below:&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%2Fqptq1mb5gknksok417ta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqptq1mb5gknksok417ta.png" alt="The source generators in action" width="457" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Afterward
&lt;/h2&gt;

&lt;p&gt;We hope you take advantage of this project and architecture, and we welcome your suggestions for this project as we want it to grow better and larger. We want to keep the community version under the MIT license forever.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
