<?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: Fedi Soltani</title>
    <description>The latest articles on DEV Community by Fedi Soltani (@fedisoltani1).</description>
    <link>https://dev.to/fedisoltani1</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4086796%2F3fb8c8e2-1b7d-4171-94e9-d8e3972d88b9.jpg</url>
      <title>DEV Community: Fedi Soltani</title>
      <link>https://dev.to/fedisoltani1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fedisoltani1"/>
    <language>en</language>
    <item>
      <title>Protecting Desktop Software: Hardware Fingerprinting and Heartbeat</title>
      <dc:creator>Fedi Soltani</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:44:18 +0000</pubDate>
      <link>https://dev.to/fedisoltani1/protecting-desktop-software-hardware-fingerprinting-and-heartbeat-53p4</link>
      <guid>https://dev.to/fedisoltani1/protecting-desktop-software-hardware-fingerprinting-and-heartbeat-53p4</guid>
      <description>&lt;p&gt;How to tie a licence to a machine, verify it continuously, and cut access the moment it stops being valid.&lt;/p&gt;

&lt;p&gt;A business plugin sold to a few dozen engineering firms raises a problem web applications never face: it runs on the customer's machine, out of the server's reach. Nothing technically prevents copying it onto ten workstations.&lt;/p&gt;

&lt;p&gt;The approach taken ties the licence to the machine rather than the user. On first launch, the plugin builds a fingerprint from hardware and system elements — MAC address, Windows information, installation coordinates — and sends it to a REST verification API. The server maps that fingerprint to a licence and returns a verdict.&lt;/p&gt;

&lt;p&gt;A single check at startup is not enough: it lets a revoked licence keep working until the next restart, which can mean weeks. A heartbeat mechanism therefore calls the platform at regular intervals. If the licence has been revoked, has expired, or the fingerprint no longer matches, access is cut within the running session.&lt;/p&gt;

&lt;p&gt;On the admin side, an ASP.NET Razor Pages interface creates, revokes and tracks licences. It is deliberately plain: the tool serves an internal team, not an online catalogue, and an over-designed interface would have cost time without returning any.&lt;/p&gt;

&lt;p&gt;An honest caveat to close on: no client-side protection is unbreakable. A .NET plugin can be decompiled, and a hardware fingerprint can be forged by someone determined. The realistic goal is not to make copying impossible — it is to make it more expensive than buying, and to give the vendor a way to revoke a licence.&lt;/p&gt;




&lt;p&gt;I write more of these at my &lt;a href="https://portfulio-vert.vercel.app/en/notes" rel="noopener noreferrer"&gt;technical notes&lt;/a&gt; — multi-tenant isolation, optimistic concurrency, AutoCAD plugin development, and other things I've actually shipped.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>security</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>Automating Hydraulic Structure Design Inside AutoCAD</title>
      <dc:creator>Fedi Soltani</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:41:32 +0000</pubDate>
      <link>https://dev.to/fedisoltani1/automating-hydraulic-structure-design-inside-autocad-3c39</link>
      <guid>https://dev.to/fedisoltani1/automating-hydraulic-structure-design-inside-autocad-3c39</guid>
      <description>&lt;p&gt;A .NET 8 plugin generating culverts and technical sheets from an alignment and a surface, hydraulic calculations included.&lt;/p&gt;

&lt;p&gt;Designing a culvert — the structure that carries water under a road — is repetitive work. The engineer reads an alignment and a surface from the model, computes the geometry, checks hydraulic behaviour, then transfers everything onto a drawing and a technical sheet. The same sequence, dozens of times per road project.&lt;/p&gt;

&lt;p&gt;The plugin reads the alignment and surface straight from the drawing through the AutoCAD .NET API, derives the structure's geometry, runs the geometric and hydraulic calculations, then generates the 3D model and the matching technical sheet. What used to take a working session becomes a command.&lt;/p&gt;

&lt;p&gt;The most instructive part of the project is not the code: it is the line between what a plugin should compute and what it should delegate. Hydraulic results are exported automatically to HY-8, the US FHWA's reference software, which acts as the verification authority. The plugin does not claim to replace a reference tool — it feeds it clean data and reads back its verdict.&lt;/p&gt;

&lt;p&gt;Working with the AutoCAD .NET API imposes constraints web work never raises. The plugin runs inside AutoCAD's process, so an unhandled exception does not fail a request: it takes down the user's session, along with their unsaved work. Transactions against the drawing database must be opened and closed with the same discipline as a SQL transaction.&lt;/p&gt;

&lt;p&gt;It is also a useful reminder for a web-oriented profile: the business does not always live in a REST API. Some industries have worked inside a desktop application for thirty years, and the value you add there is measured in engineer-hours freed, not milliseconds of latency.&lt;/p&gt;




&lt;p&gt;I write more of these at my &lt;a href="https://portfulio-vert.vercel.app/en/notes" rel="noopener noreferrer"&gt;technical notes&lt;/a&gt; — multi-tenant isolation, optimistic concurrency, desktop licensing, and other things I've actually shipped.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>autocad</category>
      <category>software</category>
    </item>
    <item>
      <title>Crossing Five .NET Versions Without Rewriting the Application</title>
      <dc:creator>Fedi Soltani</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:35:46 +0000</pubDate>
      <link>https://dev.to/fedisoltani1/crossing-five-net-versions-without-rewriting-the-application-2e30</link>
      <guid>https://dev.to/fedisoltani1/crossing-five-net-versions-without-rewriting-the-application-2e30</guid>
      <description>&lt;p&gt;From .NET 5 to .NET 10 on production projects: what an upgrade actually costs, and why waiting costs more.&lt;/p&gt;

&lt;p&gt;Over three years I have shipped applications on .NET 5, 6, 8 and 10, and led several upgrades on projects already in production. The most consistent lesson is counter-intuitive: the migration is rarely the problem. The waiting is.&lt;/p&gt;

&lt;p&gt;Moving a maintained application up one major version generally takes a few days. The same jump on an application left three versions behind becomes a project in its own right, because breaking changes accumulate and compound, and third-party libraries no longer follow the same trajectory.&lt;/p&gt;

&lt;p&gt;The approach that worked best is progressive rather than head-on: raise the target framework first, let compiler warnings drive the work, and handle behavioural changes one at a time instead of rewriting. On a government permit management project, the move from .NET 6 to .NET 8 was done exactly that way across the whole solution, with a direct benefit in reduced build and package restore times.&lt;/p&gt;

&lt;p&gt;Entity Framework Core deserves particular caution. It is the dependency where behavioural changes are quietest: a query that compiled and ran suddenly produces different SQL, or shifts from server-side to client-side evaluation. Without integration tests against a real database, that class of regression only shows up in production.&lt;/p&gt;

&lt;p&gt;Which is, incidentally, the strongest argument for integration tests against a real database under Docker and Testcontainers: they do not only validate today's feature, they make the next upgrade survivable.&lt;/p&gt;




&lt;p&gt;I write more of these at my &lt;a href="https://portfulio-vert.vercel.app/en/notes" rel="noopener noreferrer"&gt;technical notes&lt;/a&gt; — multi-tenant isolation, optimistic concurrency, AutoCAD plugin development, and other things I've actually shipped.&lt;/p&gt;

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