<?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: Jon Davis</title>
    <description>The latest articles on DEV Community by Jon Davis (@solutionsjon).</description>
    <link>https://dev.to/solutionsjon</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%2F232893%2Fde8984e4-0286-4a02-8f42-8cea91629cd9.jpg</url>
      <title>DEV Community: Jon Davis</title>
      <link>https://dev.to/solutionsjon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/solutionsjon"/>
    <language>en</language>
    <item>
      <title>CoreIdent 0.4: A Ground-Up Rewrite for .NET 10+</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:01:03 +0000</pubDate>
      <link>https://dev.to/solutionsjon/coreident-04-a-ground-up-rewrite-for-net-10-36p0</link>
      <guid>https://dev.to/solutionsjon/coreident-04-a-ground-up-rewrite-for-net-10-36p0</guid>
      <description>&lt;h1&gt;
  
  
  CoreIdent 0.4: A Ground-Up Rewrite for .NET 10+
&lt;/h1&gt;

&lt;p&gt;Hey .NET community! I have a big update to share regarding &lt;a href="https://coreident.net" rel="noopener noreferrer"&gt;CoreIdent&lt;/a&gt; : &lt;strong&gt;version 0.4 is a complete rewrite&lt;/strong&gt;, built from scratch on .NET 10, including a rewrite of the objectives and goals.&lt;/p&gt;

&lt;p&gt;If you've been following the 0.3.x releases (Phase 2, Phase 3, ID tokens, etc.), you might be wondering: &lt;em&gt;why start over?&lt;/em&gt; Let me explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Why a Rewrite?
&lt;/h2&gt;

&lt;p&gt;The 0.3.x codebase taught me a lot about what is actually needed from an identity/auth library. But it also revealed some fundamental limitations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Symmetric keys only&lt;/strong&gt; — HS256 is fine for demos, but production needs RS256/ES256 with proper JWKS publishing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passwords first&lt;/strong&gt; — The industry is moving passwordless; we should lead, not follow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;.NET 9 constraints&lt;/strong&gt; — .NET 10 brings native passkey support, better metrics, and auth API improvements we want to leverage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test infrastructure debt&lt;/strong&gt; — The test setup was getting unwieldy; we needed reusable fixtures from day one&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rather than bolt these onto 0.3.x, I decided to rebuild with the right foundations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Legacy note:&lt;/strong&gt; The 0.3.x codebase is preserved at the &lt;a href="https://github.com/stimpy77/CoreIdent/tree/legacy-0.3.x-main" rel="noopener noreferrer"&gt;&lt;code&gt;legacy-0.3.x-main&lt;/code&gt;&lt;/a&gt; tag if you need it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The New Vision
&lt;/h2&gt;

&lt;p&gt;CoreIdent's goal is to be a &lt;strong&gt;holistic authentication toolkit&lt;/strong&gt;—not just an OAuth server, but a single solution covering:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Embedded Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Drop-in authentication for ASP.NET Core apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;External Providers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google, Microsoft, GitHub integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full OAuth 2.0 / OIDC capabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client Libraries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Secure auth for MAUI, WPF, Blazor, Console apps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key shift: &lt;strong&gt;passwordless-first&lt;/strong&gt;. Email magic links and passkeys are the primary auth methods; passwords are a fallback.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Working Today
&lt;/h2&gt;

&lt;p&gt;CoreIdent 0.4 already has a solid OAuth/OIDC foundation:&lt;/p&gt;

&lt;h3&gt;
  
  
  Token Endpoint (&lt;code&gt;/auth/token&lt;/code&gt;)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;client_credentials&lt;/code&gt; grant&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;refresh_token&lt;/code&gt; grant (with rotation + theft detection)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authorization_code&lt;/code&gt; grant (PKCE required)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;password&lt;/code&gt; grant (deprecated; logs a warning)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authorization Flow
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/auth/authorize&lt;/code&gt; endpoint with consent UI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/auth/consent&lt;/code&gt; for user grant management&lt;/li&gt;
&lt;li&gt;Full PKCE enforcement&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Standards Compliance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token revocation&lt;/strong&gt; (RFC 7009)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token introspection&lt;/strong&gt; (RFC 7662)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDC discovery&lt;/strong&gt; (&lt;code&gt;/.well-known/openid-configuration&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWKS publishing&lt;/strong&gt; (&lt;code&gt;/.well-known/jwks.json&lt;/code&gt;) — public keys only&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Asymmetric Key Support
&lt;/h3&gt;

&lt;p&gt;Production-ready signing with RS256 and ES256:&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;builder&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;AddSigningKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRsa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/path/to/private-key.pem"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// or&lt;/span&gt;
&lt;span class="n"&gt;builder&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;AddSigningKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseEcdsa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/path/to/ec-key.pem"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pluggable Persistence
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In-memory stores by default (great for dev/testing)&lt;/li&gt;
&lt;li&gt;EF Core implementations for production
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&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="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CoreIdentDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;builder&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;AddEntityFrameworkCoreStores&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test Infrastructure
&lt;/h3&gt;

&lt;p&gt;Reusable fixtures and builders under &lt;a&gt;tests/&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CoreIdentTestFixture&lt;/code&gt; for integration tests&lt;/li&gt;
&lt;li&gt;Fluent builders for clients, users, scopes&lt;/li&gt;
&lt;li&gt;Assertion extensions for JWT validation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Quick Start
&lt;/h2&gt;

&lt;p&gt;Here's a minimal OAuth server in ~10 lines:&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;using&lt;/span&gt; &lt;span class="nn"&gt;CoreIdent.Core.Extensions&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;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&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="n"&gt;builder&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;AddCoreIdent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&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;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Issuer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://issuer.example"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Audience&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://resource.example"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="n"&gt;builder&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;AddSigningKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRsa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/path/to/private-key.pem"&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;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapCoreIdentEndpoints&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Token endpoint with multiple grants&lt;/li&gt;
&lt;li&gt;OIDC discovery + JWKS&lt;/li&gt;
&lt;li&gt;Authorization code flow with consent&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The roadmap is focused on making CoreIdent a true "one-stop shop":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Passwordless Authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email magic links&lt;/li&gt;
&lt;li&gt;Passkeys (leveraging .NET 10's native support)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;External Providers&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google, Microsoft, GitHub&lt;/li&gt;
&lt;li&gt;Clean provider abstraction for community additions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Client Libraries&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CoreIdent.Client&lt;/code&gt; — works in any .NET app&lt;/li&gt;
&lt;li&gt;Platform-specific: MAUI (SecureStorage), WPF (DPAPI), Blazor WASM&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Developer Experience&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project templates&lt;/li&gt;
&lt;li&gt;Better error messages&lt;/li&gt;
&lt;li&gt;OpenTelemetry metrics integration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📚 Documentation
&lt;/h2&gt;

&lt;p&gt;All planning and implementation docs are in the repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/stimpy77/CoreIdent/blob/main/docs/0.4/Developer_Guide.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Developer Guide&lt;/strong&gt;&lt;/a&gt; — Start here for practical usage&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/stimpy77/CoreIdent/blob/main/docs/0.4/Project_Overview.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Project Overview&lt;/strong&gt;&lt;/a&gt; — Vision and architecture&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/stimpy77/CoreIdent/blob/main/docs/0.4/Technical_Plan.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Technical Plan&lt;/strong&gt;&lt;/a&gt; — Specifications and interfaces&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/stimpy77/CoreIdent/blob/main/docs/0.4/DEVPLAN.md" rel="noopener noreferrer"&gt;&lt;strong&gt;DEVPLAN&lt;/strong&gt;&lt;/a&gt; — Task-level checklist&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤝 Get Involved
&lt;/h2&gt;

&lt;p&gt;CoreIdent is MIT licensed and open for contributions. If you're interested:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check out the &lt;a href="https://github.com/stimpy77/CoreIdent" rel="noopener noreferrer"&gt;repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Read the &lt;a href="https://github.com/stimpy77/CoreIdent/blob/main/docs/0.4/DEVPLAN.md" rel="noopener noreferrer"&gt;DEVPLAN&lt;/a&gt; for current tasks&lt;/li&gt;
&lt;li&gt;Run the integration tests to get familiar with the codebase&lt;/li&gt;
&lt;li&gt;Open an issue or PR!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal is to build the identity system we all wish existed—open, modular, and developer-friendly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Previous Articles
&lt;/h2&gt;

&lt;p&gt;If you followed the 0.3.x journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/solutionsjon/coreident-v035-oidc-id-tokens-real-world-gaps-and-whats-next-b3i"&gt;CoreIdent v0.3.5: OIDC ID Tokens, Real-World Gaps, and What's Next&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/solutionsjon/coreident-phase-3-milestone-oauth-20-authorization-code-flow-token-security-hardened-3lj7"&gt;Phase 3 Milestone: OAuth 2.0 Authorization Code Flow &amp;amp; Token Security Hardened&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/solutionsjon/coreident-phase-2-complete-adding-persistence-and-extensibility-2134"&gt;Phase 2 Complete: Adding Persistence and Extensibility&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for following along. Let's build something great!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>oauth</category>
      <category>authentication</category>
      <category>opensource</category>
    </item>
    <item>
      <title>C# (Maybe) Joins the Motia Family: Building Multi-Language Workflows with .NET 9</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Fri, 03 Oct 2025 21:46:58 +0000</pubDate>
      <link>https://dev.to/solutionsjon/c-maybe-joins-the-motia-family-building-multi-language-workflows-with-net-9-5h2l</link>
      <guid>https://dev.to/solutionsjon/c-maybe-joins-the-motia-family-building-multi-language-workflows-with-net-9-5h2l</guid>
      <description>&lt;h2&gt;
  
  
  What is Motia?
&lt;/h2&gt;

&lt;p&gt;If you haven't heard of &lt;a href="https://github.com/MotiaDev/motia" rel="noopener noreferrer"&gt;Motia&lt;/a&gt; yet, it's a polyglot backend framework that unifies APIs, background jobs, scheduled tasks, and AI agents into a single runtime. Instead of piecing together Express for APIs, Bull for queues, node-cron for scheduling, and separate platforms for AI agents, you write everything as "Steps" - a simple primitive with four concepts: Trigger (API/event/cron), Handler (your logic), Emit (output events), and Subscribe (input topics).&lt;/p&gt;

&lt;p&gt;The magic is that Steps can be written in different languages in the same project. Your API endpoint in TypeScript can emit an event that triggers a Python step (perfect for ML processing), which then emits to a Ruby step, all with built-in observability showing exactly what happened and when. No microservices orchestration headaches, no message broker setup, no distributed tracing configuration - it's all there.&lt;/p&gt;

&lt;p&gt;Think React's component model, but for backend workflows. That's the vision.&lt;/p&gt;

&lt;h2&gt;
  
  
  C# Support
&lt;/h2&gt;

&lt;p&gt;I'm excited to share that &lt;strong&gt;C# (.NET 9) support&lt;/strong&gt; may soon be available in Motia. Following TDD principles, I've built full C# integration that lets developers write backend services alongside TypeScript, Python, JavaScript, and Ruby - all in the same project with automatic cross-language communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it now:&lt;/strong&gt; This is currently a PR awaiting review from the Motia maintainers, but you can use it today from my fork:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/stimpy77/motia/tree/feat/csharp-dotnet-support" rel="noopener noreferrer"&gt;https://github.com/stimpy77/motia/tree/feat/csharp-dotnet-support&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The pull request to the main repo: &lt;a href="https://github.com/MotiaDev/motia/pull/769" rel="noopener noreferrer"&gt;#769&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes This Special?
&lt;/h2&gt;

&lt;p&gt;Unlike traditional polyglot systems that require glue code, this C# integration is truly seamless:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full bidirectional RPC - State operations work across all languages&lt;/li&gt;
&lt;li&gt;Zero configuration - Just write &lt;code&gt;.step.cs&lt;/code&gt; files and go&lt;/li&gt;
&lt;li&gt;Complete feature set - State management, logging, tracing, all 4 step types&lt;/li&gt;
&lt;li&gt;Type-safe - Leverage C#'s strong type system&lt;/li&gt;
&lt;li&gt;Cross-platform compatible (tested on macOS, should work on Linux/Windows)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  See It In Action
&lt;/h2&gt;

&lt;p&gt;Here's a simple example - an API endpoint in C# that communicates with event handlers in any language:&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="c1"&gt;// steps/api.step.cs&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApiStepConfig&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;static&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api"&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="s"&gt;"OrderAPI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;emits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"order.created"&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApiStepHandler&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;static&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="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;dynamic&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Set shared state&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"lastOrder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ORD-12345"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Emit event (any language can subscribe!)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"order.created"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ORD-12345"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99.99&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Log with automatic tracing&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order created"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ORD-12345"&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;201&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="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Order created successfully"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! No boilerplate, no configuration files, no infrastructure setup. Just pure business logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Development Journey
&lt;/h2&gt;

&lt;p&gt;The implementation followed strict TDD. Here are the main challenges I tackled:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Roslyn Scripting Integration
&lt;/h3&gt;

&lt;p&gt;Getting Roslyn to dynamically compile C# code at runtime while maintaining fast execution was tricky. The challenge was balancing compilation speed (~500-1000ms) with the flexibility of not requiring pre-compiled assemblies. I went with Roslyn scripting over native AOT compilation to keep the developer experience smooth.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. RPC Protocol Design
&lt;/h3&gt;

&lt;p&gt;C# needed to talk to Node.js over stdin/stdout using JSON-RPC. The initial implementation was one-way (C# sends, Node.js processes) which worked for &lt;code&gt;emit()&lt;/code&gt; and &lt;code&gt;State.Set()&lt;/code&gt;. But &lt;code&gt;State.Get()&lt;/code&gt; requires bidirectional communication - send a request, wait for a response.&lt;/p&gt;

&lt;p&gt;The breakthrough was implementing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request ID tracking with &lt;code&gt;TaskCompletionSource&lt;/code&gt; for async/await patterns&lt;/li&gt;
&lt;li&gt;A background thread continuously reading responses from stdin&lt;/li&gt;
&lt;li&gt;Response matching to complete the right pending request&lt;/li&gt;
&lt;li&gt;30-second timeouts to prevent hanging
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This now works!&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&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="n"&gt;userData&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;await&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Returns actual value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. CLI Template System
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;motia create -t csharp&lt;/code&gt; command needed to scaffold a complete project with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proper &lt;code&gt;.csproj&lt;/code&gt; configuration&lt;/li&gt;
&lt;li&gt;Example steps for all 4 types (api, event, cron, noop)&lt;/li&gt;
&lt;li&gt;README with C#-specific instructions&lt;/li&gt;
&lt;li&gt;Build system integration for cloud deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Multi-Language State Sharing
&lt;/h3&gt;

&lt;p&gt;Making sure state set by TypeScript steps could be retrieved by C# steps (and vice versa) required careful JSON serialization. C#'s &lt;code&gt;System.Text.Json&lt;/code&gt; needed to play nice with Node.js's serialization, especially for complex objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Process Management
&lt;/h3&gt;

&lt;p&gt;Each C# step spawns a .NET process. Managing process lifecycle, handling crashes gracefully, and ensuring proper cleanup without memory leaks took some careful work with Node's process communication APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Multi-Language Example
&lt;/h2&gt;

&lt;p&gt;Imagine building an order processing system where each language does what it does best:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C# API Step&lt;/strong&gt; (HTTP endpoint):&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;static&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="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;dynamic&lt;/span&gt; &lt;span class="n"&gt;ctx&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;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orderData&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;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"order.created"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orderData&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="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;201&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="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"123"&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;&lt;strong&gt;Python Event Step&lt;/strong&gt; (ML processing):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&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;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Process with scikit-learn, tensorflow, etc.
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;topic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order.analyzed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;risk_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.95&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;TypeScript Event Step&lt;/strong&gt; (Business logic):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;emit&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;order&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Handle payment processing&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;order.completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;All three steps communicate automatically through Motia's event system with built-in observability!&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture Highlights
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Roslyn Scripting&lt;/strong&gt; - Dynamic C# compilation for rapid development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RPC over stdin/stdout&lt;/strong&gt; - Efficient bidirectional communication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process isolation&lt;/strong&gt; - Each C# step runs in its own process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic discovery&lt;/strong&gt; - Just name files &lt;code&gt;*.step.cs&lt;/code&gt; and Motia finds them&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Performance Characteristics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Process spawn&lt;/strong&gt;: ~200-300ms (first request)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roslyn compilation&lt;/strong&gt;: ~500-1000ms (dynamic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RPC round-trip&lt;/strong&gt;: ~1-5ms per operation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory overhead&lt;/strong&gt;: ~40-60MB per process&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Future Optimizations (Phase 7)
&lt;/h3&gt;

&lt;p&gt;The implementation is feature-complete and well-tested, but here's what could improve performance further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Process pooling&lt;/strong&gt; - Reuse C# processes (50-70% faster cold starts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assembly caching&lt;/strong&gt; - Reduce compilation time by 80%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NuGet package&lt;/strong&gt; - Official &lt;code&gt;Motia.Core&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source generators&lt;/strong&gt; - Reduce boilerplate with code generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware support&lt;/strong&gt; - C# middleware chains for API steps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F# support&lt;/strong&gt; - Functional programming on .NET&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;The implementation includes comprehensive testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit tests&lt;/strong&gt; - Config parsing, execution, state operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration tests&lt;/strong&gt; - Full workflow validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E2E tests&lt;/strong&gt; - Template creation and deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform testing&lt;/strong&gt; - Verified on macOS (compatible with Linux and Windows)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All tests passing, including the critical bidirectional state operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying It Out
&lt;/h2&gt;

&lt;p&gt;If you want to test this before it's (potentially) merged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone my fork&lt;/span&gt;
git clone https://github.com/stimpy77/motia.git
&lt;span class="nb"&gt;cd &lt;/span&gt;motia
git checkout feat/csharp-dotnet-support

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
pnpm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Build&lt;/span&gt;
pnpm build

&lt;span class="c"&gt;# Try the C# template&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp
npx ../motia/packages/snap/dist/index.js create &lt;span class="nt"&gt;-t&lt;/span&gt; csharp my-csharp-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-csharp-app
npx motia dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or wait to see if the maintainers merge &lt;a href="https://github.com/MotiaDev/motia/pull/769" rel="noopener noreferrer"&gt;PR #769&lt;/a&gt;, then you can just use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx motia@latest create &lt;span class="nt"&gt;-t&lt;/span&gt; csharp my-csharp-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;.NET 9 SDK - &lt;a href="https://dotnet.microsoft.com/download/dotnet/9.0" rel="noopener noreferrer"&gt;Download here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Node.js 20+&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step Types Available
&lt;/h2&gt;

&lt;p&gt;C# supports all 4 Motia step types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;Example Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;api&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP Request&lt;/td&gt;
&lt;td&gt;REST endpoints, webhooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;event&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Topic subscription&lt;/td&gt;
&lt;td&gt;Background processing, queues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;cron&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Schedule&lt;/td&gt;
&lt;td&gt;Daily reports, cleanup jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;noop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;External processes, UI helpers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live Branch&lt;/strong&gt;: &lt;a href="https://github.com/stimpy77/motia/tree/feat/csharp-dotnet-support" rel="noopener noreferrer"&gt;feat/csharp-dotnet-support&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pull Request&lt;/strong&gt;: &lt;a href="https://github.com/MotiaDev/motia/pull/769" rel="noopener noreferrer"&gt;#769 on MotiaDev/motia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The PR includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete implementation with bidirectional RPC&lt;/li&gt;
&lt;li&gt;Comprehensive documentation&lt;/li&gt;
&lt;li&gt;All tests passing&lt;/li&gt;
&lt;li&gt;Phase 7 roadmap with future enhancements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For C# Developers:&lt;/strong&gt; Build modern backends without leaving the .NET ecosystem. Leverage your existing skills and libraries with strong typing and excellent IDE support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Motia Users:&lt;/strong&gt; Use the best tool for each job - C# for APIs, Python for ML, TypeScript for business logic. Seamless cross-language communication with single deployment and unified observability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the Community:&lt;/strong&gt; A reference implementation for multi-language frameworks with a working bidirectional RPC pattern and comprehensive testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;The implementation is feature-complete with all tests passing. Phase 7 ideas for future optimization:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;NuGet package&lt;/strong&gt; - Official &lt;code&gt;Motia.Core&lt;/code&gt; for better IDE support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source generators&lt;/strong&gt; - Auto-generate config from attributes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; - Process pooling and assembly caching&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware&lt;/strong&gt; - C# middleware chains like TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F# support&lt;/strong&gt; - Functional programming on .NET&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Feedback Welcome
&lt;/h2&gt;

&lt;p&gt;If you try this out, I'd love to hear how it goes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Found a bug? &lt;a href="https://github.com/MotiaDev/motia/issues" rel="noopener noreferrer"&gt;Open an issue&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Have ideas? Comment on &lt;a href="https://github.com/MotiaDev/motia/pull/769" rel="noopener noreferrer"&gt;PR #769&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Like it? Star the &lt;a href="https://github.com/MotiaDev/motia" rel="noopener noreferrer"&gt;repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Built something? Share in the &lt;a href="https://discord.gg/nJFfsH5d6v" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main Repository&lt;/strong&gt;: &lt;a href="https://github.com/MotiaDev/motia" rel="noopener noreferrer"&gt;MotiaDev/motia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://motia.dev" rel="noopener noreferrer"&gt;motia.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt;: &lt;a href="https://github.com/MotiaDev/motia-examples" rel="noopener noreferrer"&gt;motia-examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C# Examples Guide&lt;/strong&gt;: &lt;a href="https://github.com/stimpy77/motia/blob/feat/csharp-dotnet-support/packages/core/src/csharp/EXAMPLES_GUIDE.md" rel="noopener noreferrer"&gt;EXAMPLES_GUIDE.md&lt;/a&gt; - Blueprint for C# example implementations&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Built with:&lt;/strong&gt; .NET 9 and TDD methodology.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full disclosure (because honesty is fun):&lt;/strong&gt; I built this entire implementation using Claude 4.5 Sonnet in Cursor. Every line of C# runner code, RPC protocol implementation, test fixtures, documentation, and yes, even this post explaining how I used AI to write it, was pair-programmed with AI. The irony is not lost on me. The TDD approach and architectural decisions were collaborative between human and AI, which is a fancy way of saying I described what I wanted and Claude wrote it while I just sat there barking at it when it broke.&lt;/p&gt;

&lt;p&gt;If this bothers you, buckle up - this is how things are getting done now and it's only going to accelerate. 🤷&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Special thanks&lt;/strong&gt; to the Motia community and the existing Python/Ruby implementations that served as reference patterns.&lt;/p&gt;

&lt;p&gt;What would you build with C# + Motia? Drop a comment below.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;#csharp #dotnet #backend #opensource #developers #api #microservices #eventdriven&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>CoreIdent v0.3.5: OIDC ID Tokens, Real-World Gaps, and What’s Next</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Sat, 19 Apr 2025 21:09:11 +0000</pubDate>
      <link>https://dev.to/solutionsjon/coreident-v035-oidc-id-tokens-real-world-gaps-and-whats-next-b3i</link>
      <guid>https://dev.to/solutionsjon/coreident-v035-oidc-id-tokens-real-world-gaps-and-whats-next-b3i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;CoreIdent is on a mission to make robust, standards-based authentication and identity &lt;em&gt;actually&lt;/em&gt; developer-friendly. In &lt;a href="https://dev.to/solutionsjon/coreident-phase-3-milestone-oauth-20-authorization-code-flow-token-security-hardened-3lj7"&gt;Phase 3&lt;/a&gt;, we delivered hardened OAuth 2.0 Authorization Code flows and security improvements. Now, with v0.3.5, we’re taking the next step: real OIDC ID Token support, smarter claims, and a roadmap for practical, real-world adoption.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🚀 What’s New in v0.3.5
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OIDC-Compliant ID Token Issuance:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
ID Tokens are now fully standards-based, with claims like &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; sourced from your user store (not just the username field). This means better compatibility and flexibility for modern apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comprehensive Testing:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We’ve added a full suite of unit and integration tests for all ID Token claim variations, including nonce round-trip and scope-based claim inclusion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DEVPLAN: Real-World Gaps Checklist:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We’re not just checking spec boxes anymore. Our new Phase 3 checklist documents where spec-compliance isn’t enough—covering custom claims, consent UI, token revocation/introspection, dynamic client registration, key rotation, and more.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;All Packages Updated:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Core, EF, and DelegatedUserStore packages are now at 0.3.5.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧐 Why This Matters
&lt;/h2&gt;

&lt;p&gt;Many identity platforms “pass the tests” but frustrate real developers with missing extension points, hard-coded behaviors, or lack of practical features. CoreIdent is committed to surfacing and fixing these gaps—so your apps work the way you expect, not just the way the spec says.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔭 What’s Next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tackling the new checklist: custom claims, consent, dynamic registration, and more&lt;/li&gt;
&lt;li&gt;Minimal, extensible UI package for login, consent, and error handling&lt;/li&gt;
&lt;li&gt;Real-world interop and negative testing&lt;/li&gt;
&lt;li&gt;Community feedback and contributions welcome!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📚 Read More
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/solutionsjon/coreident-phase-3-milestone-oauth-20-authorization-code-flow-token-security-hardened-3lj7"&gt;Phase 3 Milestone: OAuth 2.0 Authorization Code Flow &amp;amp; Token Security Hardened&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/solutionsjon/coreident-phase-2-complete-adding-persistence-and-extensibility-2134"&gt;Phase 2 Complete: Adding Persistence and Extensibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/solutionsjon/coming-soon-announcing-coreident-e29"&gt;Announcing CoreIdent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Ready to try CoreIdent or contribute?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Check out the &lt;a href="https://github.com/stimpy77/CoreIdent" rel="noopener noreferrer"&gt;repo&lt;/a&gt;, and let’s build the identity system we all wish existed!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>security</category>
      <category>oidc</category>
      <category>oauth2</category>
    </item>
    <item>
      <title>CoreIdent Phase 3 Milestone: OAuth 2.0 Authorization Code Flow &amp; Token Security Hardened!</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Thu, 17 Apr 2025 07:27:33 +0000</pubDate>
      <link>https://dev.to/solutionsjon/coreident-phase-3-milestone-oauth-20-authorization-code-flow-token-security-hardened-3lj7</link>
      <guid>https://dev.to/solutionsjon/coreident-phase-3-milestone-oauth-20-authorization-code-flow-token-security-hardened-3lj7</guid>
      <description>&lt;p&gt;Hey .NET developers!&lt;/p&gt;

&lt;p&gt;Following up on my &lt;a href="https://dev.to/solutionsjon/coreident-phase-2-complete-adding-persistence-and-extensibility-2134"&gt;previous announcement about Phase 2&lt;/a&gt;, I'm thrilled to share that the first major feature set for Phase 3 of CoreIdent is complete and published in &lt;strong&gt;version 0.3.1&lt;/strong&gt; on NuGet!&lt;/p&gt;

&lt;p&gt;This milestone lays critical groundwork for CoreIdent becoming a robust OAuth 2.0 / OpenID Connect provider, moving significantly beyond the basic registration/login established in earlier phases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's New in v0.3.1 (Phase 3 Progress)?
&lt;/h2&gt;

&lt;p&gt;This update was packed with foundational OAuth features and significant internal improvements stemming from rigorous testing:&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Authorization Code Flow + PKCE
&lt;/h3&gt;

&lt;p&gt;This is the cornerstone for securely authenticating users in web applications, Single Page Applications (SPAs), and native/mobile clients. CoreIdent now includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;/auth/authorize&lt;/code&gt; Endpoint:&lt;/strong&gt; Handles the initial authorization request, validates client/redirect URIs, checks user authentication, and issues authorization codes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;/auth/token&lt;/code&gt; Endpoint Enhancement:&lt;/strong&gt; Added support for the &lt;code&gt;authorization_code&lt;/code&gt; grant type. It securely exchanges the code for tokens, validating the client and performing &lt;strong&gt;PKCE (Proof Key for Code Exchange)&lt;/strong&gt; verification for enhanced security against code interception attacks.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;OIDC ID Tokens:&lt;/strong&gt; Basic OpenID Connect ID Tokens are now issued alongside access/refresh tokens during the Authorization Code flow, containing essential user claims.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔒 Hardened Refresh Token Security
&lt;/h3&gt;

&lt;p&gt;Based on deep testing and refinement, refresh token handling is now significantly more secure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Secure Handle Storage:&lt;/strong&gt; Refresh tokens now store the &lt;em&gt;raw&lt;/em&gt; handle as the primary key in the database (&lt;code&gt;Handle&lt;/code&gt; column) while also storing a separate, &lt;strong&gt;securely hashed&lt;/strong&gt; version (&lt;code&gt;HashedHandle&lt;/code&gt; column, using SHA-256 salted with user+client ID). The raw handle is returned to the client, but storage relies on the hash, preventing exposure if the database is compromised. (Documentation updated to reflect this).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Token Theft Detection (Default: RevokeFamily):&lt;/strong&gt; The default security posture (&lt;code&gt;TokenSecurity.EnableTokenFamilyTracking = true&lt;/code&gt;, &lt;code&gt;TokenSecurity.TokenTheftDetectionMode = RevokeFamily&lt;/code&gt;) now actively combats token theft. If a &lt;em&gt;consumed&lt;/em&gt; refresh token is reused, CoreIdent not only rejects it but also &lt;strong&gt;immediately revokes all other active tokens belonging to the same rotation family&lt;/strong&gt;. This significantly mitigates the risk of a compromised token being used further.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Test Suite Overhaul &amp;amp; Bug Fixes
&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;major&lt;/em&gt; effort went into strengthening the integration test suite (&lt;code&gt;CoreIdent.Integration.Tests&lt;/code&gt;). This involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Fixing numerous bugs related to DbContext lifetime/scoping within &lt;code&gt;WebApplicationFactory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Ensuring reliable database migration and seeding within test setups.&lt;/li&gt;
&lt;li&gt;  Correcting logic in token storage/lookup (&lt;code&gt;Handle&lt;/code&gt; vs &lt;code&gt;HashedHandle&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Resolving subtle JSON deserialization issues caused by duplicate type definitions.&lt;/li&gt;
&lt;li&gt;  Aligning test assertions with the actual (and intended) behavior of features like &lt;code&gt;RevokeFamily&lt;/code&gt; token theft detection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having passing, reliable integration tests is crucial for confidence and stability!&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Updated Documentation
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;README.md&lt;/code&gt; and &lt;code&gt;docs/Developer_Training_Guide.md&lt;/code&gt; have been updated to reflect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Correct endpoint paths (using the &lt;code&gt;/auth&lt;/code&gt; prefix).&lt;/li&gt;
&lt;li&gt;  Clarified details on refresh token storage (raw vs. hashed handles).&lt;/li&gt;
&lt;li&gt;  Explanation of the &lt;code&gt;RevokeFamily&lt;/code&gt; token theft detection behavior.&lt;/li&gt;
&lt;li&gt;  Notes on DI registration order and test setup best practices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Phase 3 continues with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Client Credentials Flow implementation.&lt;/li&gt;
&lt;li&gt;  OIDC Discovery endpoints (&lt;code&gt;/.well-known/openid-configuration&lt;/code&gt;, &lt;code&gt;/.well-known/jwks.json&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Further ID Token refinements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get Involved!
&lt;/h2&gt;

&lt;p&gt;CoreIdent aims to be the modern, developer-centric identity solution the .NET community deserves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Check out the code:&lt;/strong&gt; &lt;a href="https://github.com/stimpy77/CoreIdent" rel="noopener noreferrer"&gt;https://github.com/stimpy77/CoreIdent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Try the NuGet packages:&lt;/strong&gt; &lt;code&gt;CoreIdent.Core&lt;/code&gt;, &lt;code&gt;CoreIdent.Storage.EntityFrameworkCore&lt;/code&gt;, &lt;code&gt;CoreIdent.Adapters.DelegatedUserStore&lt;/code&gt; (v0.3.1)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Star the repo!&lt;/strong&gt; ⭐&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Provide feedback:&lt;/strong&gt; Open issues, start discussions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's build this together!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;What are your biggest pain points with existing .NET identity solutions? Share in the comments!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>authentication</category>
      <category>security</category>
    </item>
    <item>
      <title>Introducing ConsoleInk.NET: Streaming Markdown Rendering for .NET Console Apps</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Sun, 13 Apr 2025 06:36:22 +0000</pubDate>
      <link>https://dev.to/solutionsjon/introducing-consoleinknet-streaming-markdown-rendering-for-net-console-apps-3bc5</link>
      <guid>https://dev.to/solutionsjon/introducing-consoleinknet-streaming-markdown-rendering-for-net-console-apps-3bc5</guid>
      <description>&lt;p&gt;Today I'm excited to announce the first release of &lt;strong&gt;ConsoleInk.NET&lt;/strong&gt;, a lightweight, zero-dependency .NET library for rendering Markdown directly in console applications using ANSI formatting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ConsoleInk.NET?
&lt;/h2&gt;

&lt;p&gt;ConsoleInk.NET transforms Markdown text into beautifully formatted console output, with a streaming-first design that processes content incrementally as it arrives - perfect for real-time display of documentation, chat messages, or any text that benefits from Markdown's readability.&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="c1"&gt;// Simple example&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;markdown&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"# Hello Console!\nThis is **bold** and *italic* text."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;MarkdownConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Another Markdown Library?
&lt;/h2&gt;

&lt;p&gt;Most Markdown libraries focus on HTML conversion or require complex dependency chains. ConsoleInk.NET addresses a specific need: &lt;strong&gt;direct console rendering&lt;/strong&gt; with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero external dependencies&lt;/strong&gt; - just the .NET BCL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming-first architecture&lt;/strong&gt; - process content as it arrives&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ANSI formatting&lt;/strong&gt; - for modern terminal experiences&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple API&lt;/strong&gt; - intuitive for both one-shot and streaming scenarios&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;ConsoleInk.NET supports a wide range of Markdown syntax:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text Formatting&lt;/strong&gt;: Headings, paragraphs, emphasis (bold, italic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured Content&lt;/strong&gt;: Lists (ordered, unordered, task lists), blockquotes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt;: Inline code, indented code blocks, fenced code blocks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Links&lt;/strong&gt;: Inline links with true OSC-8 hyperlinks (terminal-dependent)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tables&lt;/strong&gt;: Basic GFM table support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Theming&lt;/strong&gt;: Customizable ANSI color schemes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hyperlinks
&lt;/h3&gt;

&lt;p&gt;One standout feature is support for true clickable hyperlinks in terminals that support the OSC-8 spec:&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&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;MarkdownRenderOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;UseHyperlinks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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;markdown&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Visit [GitHub](https://github.com/) for more info."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;MarkdownConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In terminals without hyperlink support, it falls back to styled text with the URL displayed in parentheses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Blocks
&lt;/h3&gt;

&lt;p&gt;Both indented and fenced code blocks are supported with careful handling of line breaks and indentation:&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="c1"&gt;// Example showing fenced code blocks&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;markdown&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="s"&gt;"
&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Code&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
csharp&lt;br&gt;
// This will be rendered with proper spacing&lt;br&gt;
if (x &amp;gt; 0)&lt;br&gt;
{&lt;br&gt;
    Console.WriteLine(""Hello"");&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;";
MarkdownConsole.Render(markdown, Console.Out);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Not Supported (Yet)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Advanced HTML&lt;/strong&gt;: HTML tags are stripped by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax Highlighting&lt;/strong&gt;: Code blocks are styled but not syntax-highlighted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Math Notation&lt;/strong&gt;: LaTeX/MathJax content is rendered as plain text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagrams&lt;/strong&gt;: Mermaid and similar diagram markup is displayed as plain text&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementation Approach
&lt;/h2&gt;

&lt;p&gt;ConsoleInk.NET uses a state machine processor that handles Markdown incrementally and renders directly as it processes content. This approach is optimized for line-by-line rendering and enables live display of content as it arrives.&lt;/p&gt;

&lt;p&gt;The streaming design follows a clean TextWriter-like pattern:&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="c1"&gt;// Streaming example&lt;/span&gt;
&lt;span class="k"&gt;using&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;writer&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;MarkdownConsoleWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Process content as it arrives&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"# Streaming Demo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content is processed **incrementally**."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Disposal handles completion automatically&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Install from NuGet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package ConsoleInk.Net &lt;span class="nt"&gt;--version&lt;/span&gt; 0.1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic usage:&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;using&lt;/span&gt; &lt;span class="nn"&gt;ConsoleInk.Net&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// One-shot rendering&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;markdown&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"# Hello\n\nThis is a **test**."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;MarkdownConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// With custom options&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&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;MarkdownRenderOptions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ConsoleWidth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Theme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConsoleTheme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;UseHyperlinks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;MarkdownConsole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Future Plans
&lt;/h2&gt;

&lt;p&gt;This is just the beginning for ConsoleInk.NET. Future releases will add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dedicated PowerShell module for seamless PS integration&lt;/li&gt;
&lt;li&gt;Extended GFM support&lt;/li&gt;
&lt;li&gt;More theming options&lt;/li&gt;
&lt;li&gt;Improved table handling&lt;/li&gt;
&lt;li&gt;Better rendering of complex nested structures&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Today
&lt;/h2&gt;

&lt;p&gt;ConsoleInk.NET is open source (MIT license) and available on &lt;a href="https://www.nuget.org/packages/ConsoleInk.Net/" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt;. The source code is on &lt;a href="https://github.com/stimpy77/ConsoleInk.NET" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Give it a try for your next console application that needs beautiful documentation, help text, or any Markdown-formatted content!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you used Markdown rendering in console applications before? What features would you like to see in future releases? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CoreIdent Phase 2 Complete: Adding Persistence and Extensibility</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Sun, 13 Apr 2025 06:29:57 +0000</pubDate>
      <link>https://dev.to/solutionsjon/coreident-phase-2-complete-adding-persistence-and-extensibility-2134</link>
      <guid>https://dev.to/solutionsjon/coreident-phase-2-complete-adding-persistence-and-extensibility-2134</guid>
      <description>&lt;p&gt;Hey .NET community! I'm excited to share that Phase 2 of &lt;a href="https://github.com/stimpy77/CoreIdent" rel="noopener noreferrer"&gt;CoreIdent&lt;/a&gt; is now complete, building on the foundation I shared in my &lt;a href="https://dev.to/stimpy77/coming-soon-announcing-coreident-e29"&gt;initial announcement&lt;/a&gt;. This milestone brings us one step closer to a comprehensive, modern identity solution for .NET developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's New in Phase 2?
&lt;/h2&gt;

&lt;p&gt;Phase 2 focused on two critical aspects: persistence and extensibility. Let me walk you through what's been accomplished:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Entity Framework Core Storage
&lt;/h3&gt;

&lt;p&gt;The new &lt;code&gt;CoreIdent.Storage.EntityFrameworkCore&lt;/code&gt; project provides a full-featured persistence layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CoreIdentDbContext&lt;/code&gt; with properly configured entity relationships&lt;/li&gt;
&lt;li&gt;EF Core implementations for all key interfaces:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;EfUserStore&lt;/code&gt; for user management&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EfRefreshTokenStore&lt;/code&gt; for secure token handling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EfClientStore&lt;/code&gt; for OAuth client configuration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EfScopeStore&lt;/code&gt; for scope management&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Migrations support for easy database setup&lt;/li&gt;

&lt;li&gt;Extension methods for seamless integration: &lt;code&gt;AddCoreIdentEntityFrameworkStores&amp;lt;TContext&amp;gt;()&lt;/code&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Initial SQLite support ensures developers can get started quickly, while the architecture supports any EF Core provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Delegated User Store Adapter
&lt;/h3&gt;

&lt;p&gt;One of the most requested features was integration with existing user databases. The new &lt;code&gt;CoreIdent.Adapters.DelegatedUserStore&lt;/code&gt; project makes this possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A flexible adapter pattern for connecting to external user stores&lt;/li&gt;
&lt;li&gt;Simple delegate-based configuration&lt;/li&gt;
&lt;li&gt;Support for read operations against existing systems&lt;/li&gt;
&lt;li&gt;Clean extension methods: &lt;code&gt;AddCoreIdentDelegatedUserStore()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means you can now use CoreIdent with your existing ASP.NET Identity database, custom user tables, or even external identity providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Refined Interfaces and Models
&lt;/h3&gt;

&lt;p&gt;The core interfaces have been significantly enhanced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IUserStore&lt;/code&gt; now includes comprehensive methods for password management, claims, and lockout functionality&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;IRefreshTokenStore&lt;/code&gt;, &lt;code&gt;IClientStore&lt;/code&gt;, and &lt;code&gt;IScopeStore&lt;/code&gt; interfaces provide clear contracts&lt;/li&gt;
&lt;li&gt;Model refinements throughout the codebase enhance consistency and security&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Robust Refresh Token Implementation
&lt;/h3&gt;

&lt;p&gt;Security was a major focus in Phase 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full token rotation implementation (old tokens automatically invalidated when used)&lt;/li&gt;
&lt;li&gt;Proper token hashing and validation&lt;/li&gt;
&lt;li&gt;Prevention of common token replay attacks&lt;/li&gt;
&lt;li&gt;Clean integration with the persistence layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next: Phase 3
&lt;/h2&gt;

&lt;p&gt;With Phase 2 complete, development is now focused on Phase 3: Core OAuth 2.0 and OpenID Connect server mechanics. This will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorization Code flow with PKCE&lt;/li&gt;
&lt;li&gt;Client Credentials flow&lt;/li&gt;
&lt;li&gt;OpenID Connect discovery endpoints&lt;/li&gt;
&lt;li&gt;ID Token issuance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The groundwork laid in Phases 1 and 2 provides a solid foundation for these advanced features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Involved
&lt;/h2&gt;

&lt;p&gt;CoreIdent is being built as a gift to the .NET community. If you're interested in modern, secure, and developer-friendly authentication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check out the &lt;a href="https://github.com/stimpy77/CoreIdent" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Star the project to show your support&lt;/li&gt;
&lt;li&gt;Contribute ideas, issues, or pull requests&lt;/li&gt;
&lt;li&gt;Try it out and provide feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're building a small side project or an enterprise application, CoreIdent aims to make authentication both secure and painless.&lt;/p&gt;

&lt;p&gt;I'm excited to continue this journey and bring a truly modern identity solution to .NET developers. Stay tuned for Phase 3!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What aspects of identity management in .NET do you find most challenging? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Coming soon: Announcing CoreIdent</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Sat, 12 Apr 2025 08:25:13 +0000</pubDate>
      <link>https://dev.to/solutionsjon/coming-soon-announcing-coreident-e29</link>
      <guid>https://dev.to/solutionsjon/coming-soon-announcing-coreident-e29</guid>
      <description>&lt;p&gt;Coming soon: Announcing CoreIdent! 🎉 I’m working on a new open-source, dev-friendly identity &amp;amp; auth solution for modern #dotnet. Built on .NET 9+, modular, and aiming to simplify secure logins (incl. Passkeys, Web3).&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://github.com/stimpy77/CoreIdent" rel="noopener noreferrer"&gt;https://github.com/stimpy77/CoreIdent&lt;/a&gt; #opensource #authentication #identity&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%2Ff4muy4odwvkfpnnin7zb.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%2Ff4muy4odwvkfpnnin7zb.png" alt="Image description" width="600" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CoreIdent is a solo project I just started on—a modern, open-source identity and authentication solution for the .NET ecosystem, built from years of wrestling with software challenges. When Identity Server went commercial, it left a gap in the .NET community. There aren’t many .NET-based options that deliver both serious power and easy setup, whether you’re coding for a startup or an enterprise app. CoreIdent is my stab at fixing that, leaning on convention over configuration, modularity, and integrations that just work.&lt;/p&gt;

&lt;p&gt;I want secure authentication and authorization to feel effortless, whether you’re grinding on a side project or a mission-critical system. CoreIdent will support traditional identity standards and dive into newer stuff like Decentralized Identity (DID), Passkeys, and Web3 auth. Its pluggable provider model means you can tailor it for anything—from quick MVPs to massive deployments—without getting stuck with vendor lock-in.&lt;/p&gt;

&lt;p&gt;I’m early in the build, crafting this alone as a future gift to the .NET community. CoreIdent runs on .NET 9+ to tap into the latest performance and security features, keeping it lightweight but ready for real-world demands. I’m working on support for OAuth 2.0, OpenID Connect, and JWT-based flows, with integrations for players like Google and Microsoft built in. Got custom auth needs? The modular design will let you plug in your own providers or handle oddball requirements without a fuss. My target: get auth running in minutes, not days, because I’ve felt the pain of setup nightmares.&lt;/p&gt;

&lt;p&gt;This project is me trying to build what I always wanted: a dependable, flexible identity solution that doesn’t skimp on security or simplicity. CoreIdent’s being designed for serious business use—think e-commerce platforms, SaaS products, or microservices setups—while staying approachable for smaller gigs. Picture starting a new app and crushing authentication before your standup meeting, or messing around with passwordless logins and blockchain-based identity without losing your mind. Solo dev with a dream? Team scaling a product? I want CoreIdent to be your go-to. It’ll be fully open source, so you can fork it, tweak it, or run wild with it. I’ve spent years seeing identity systems trip up or shine, and I’m channeling that into something secure, practical, and—why not?—kinda delightful to use.&lt;/p&gt;

&lt;p&gt;Swing by the GitHub repo, drop a star, share your thoughts, or just watch it come together. Let’s make identity in .NET something you can count on, whatever you’re building.&lt;/p&gt;

&lt;p&gt;Oh yeah, one more thing. Am I leveraging AI? Of course. Did I leverage AI to post this? Dude. Get with the times. Our experience drives AI now. We command and conquer.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How do you manage focus in ramp-up?</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Mon, 21 Oct 2019 08:35:21 +0000</pubDate>
      <link>https://dev.to/solutionsjon/how-do-you-manage-focus-in-ramp-up-1p4e</link>
      <guid>https://dev.to/solutionsjon/how-do-you-manage-focus-in-ramp-up-1p4e</guid>
      <description>&lt;p&gt;Just a brief question. How do you manage to maintain focus in ramp-up (technical self-training)? One of my great deficiencies over my career has occasionally been shown to be a failure to have deep understanding of some of the tech stack components I claim to support. And the root cause of this is that when the time came that I needed to learn up on my stuff, I got ADHD of some sort, and never followed through with deep diving and getting to the end. &lt;/p&gt;

&lt;p&gt;22 years in the field, I've seen a lot of action and a lot of evolution of technology and watched a lot of technology trends come and go. Every new thing I learn makes me reminisce about something else I knew, or something else I heard about, or wonder what happened to that one guy who showed me how he dabbled in that such and such ...&lt;/p&gt;

&lt;p&gt;I'll read a paragraph from a tutorial, and nitpick specific details, and ask questions about those details, and find myself spending thirty minutes researching those tangents. Eventually I'll realize I got off on a tangent--but not before taking a mental break and finding some other music to listen to, then researching what happened to that old musical artist I used to love years ago, or whatever--and then finally return to the &lt;em&gt;same paragraph&lt;/em&gt; to finally implement the detail that the tutorial is telling me to do.&lt;/p&gt;

&lt;p&gt;Rinse, repeat, for &lt;strong&gt;&lt;em&gt;every. single. paragraph.&lt;/em&gt;&lt;/strong&gt;  As a result, twenty-minute tutorials take me two or three days to complete, or some ten or so hours. Similarly for video; I am constantly having to rewind because I think too hard on each point; a two hour video can take days (many hours) to wade through. I'm more or less enriched for all this, but it makes me a less competent professional when I put in equal time as my peers--I have to dedicate so much more time to the craft than they do, I think.&lt;/p&gt;

&lt;p&gt;When I know my stuff I am pretty good at it, but I am floored by the depth and resolve and detail that my peers are able to demonstrate when they lay out their abilities and put them on full display. Yes, it makes me jealous. And frustrated.&lt;/p&gt;

&lt;p&gt;I'm serious. Is there a particular kind of psychologist or other professional I should be talking to? Maybe there is some "focus pill" I can take.&lt;/p&gt;

&lt;p&gt;Are there simple tactics or mind tricks you use to keep the ball rolling and on track?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Prelude to a Blogging Reset</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Sun, 20 Oct 2019 08:03:21 +0000</pubDate>
      <link>https://dev.to/solutionsjon/prelude-to-a-blogging-reset-7ai</link>
      <guid>https://dev.to/solutionsjon/prelude-to-a-blogging-reset-7ai</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a mirror/clone of a post of the same name on my blog at &lt;a href="http://www.jondavis.net/techblog/" rel="noopener noreferrer"&gt;http://www.jondavis.net/techblog/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started blogging in around 2002/2003 when Blogger and Radio UserLand were inspirations for me to create a desktop blogging app I called PowerBlog. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Archive.org archive of my old PowerBlog.net software download web site: &lt;br&gt;
&lt;a href="https://web.archive.org/web/20031010203956/http://powerblog.net/" rel="noopener noreferrer"&gt;https://web.archive.org/web/20031010203956/http://powerblog.net/&lt;/a&gt;&lt;br&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%2F97sczvrmlgsc2cy8qsfy.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%2F97sczvrmlgsc2cy8qsfy.jpg" alt="PowerBlog" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://web.archive.org/web/20031010203956/http://powerblog.net/" rel="noopener noreferrer"&gt;&lt;/a&gt;My motivations were three:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; To grow my skill set as a software developer.&lt;/li&gt;
&lt;li&gt; To see if I could maybe make a living building and selling home-grown software. (PowerBlog was available for sale, but didn't sell.)&lt;/li&gt;
&lt;li&gt; To write, and write, and write. My brain was churning, and I wanted to divulge my thoughts out loud. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PowerBlog was initially written in VB6. It consisted of an instance of the Internet Explorer WebBrowser COM object to drive a true WYSIWYG experience, design philosophies similar to those of Outlook Express (an e-mail and newsgroup client), and a publish mechanism component model including support for user-defined publishing scripts using the Active Scripting (VBScript/JScript) runtime component. When .NET v1.1 came out, I rewrote PowerBlog in C#, reusing the same components from Microsoft but adding more features like XML-RPC--by which I built my own client/server libraries with self-documenting HTML output similar to ASP.NET's .asmx behavior--and style synchronization so that the user could edit in the same CSS style as the page itself. I tried to sell PowerBlog for $10 to $20 per download. It didn't sell. That's kind of okay, the value of my efforts was found in my skills ramp-up and in my having a tool for my own writing.&lt;/p&gt;

&lt;p&gt;PowerBlog got Microsoft's attention. Three things happened, all of a sudden, with Microsoft: 1) the Windows Live initiative kicked off blogging from their web site (which they've since shuttered), 2) Microsoft interviewed me, and 3) Windows Live Writer was written, stealing most of the good ideas I had in PowerBlog (admittedly tidbits of the ideas of PowerBlog were stolen from another app called W.bloggar). I got nothin for it but some bragging rights for the ideas. &lt;/p&gt;

&lt;p&gt;I was broke. My motivators to go out on my own (taxes-related need to go offline to do some research) subsided. So I stopped development and went back out into the workforce. When .NET 2.0 came out along with a new version of Internet Explorer, it broke PowerBlog permanently. Microsoft published WebBrowser components that directly collided with the WebBrowser components I had created for PowerBlog. So PowerBlog isn't available today--it will just crash for you if you try--and I couldn't even build my own source code anymore, without finding an old Windows XP box with an old version of Visual Studio and .NET Framework 1.1. It just wasn't worth the hassle, so I never bothered. Maintenance was immediately halted. PowerBlog.net went offline. I didn't much care. I did need to keep blogging and writing, so eventually I found BlogEngine.net and transferred my technical blog content to it. I updated the blog engine code once or twice as it evolved, but eventually I just let it sit dormant.&lt;/p&gt;

&lt;p&gt;So that's where my tech blog instance stands today. &lt;a href="http://www.jondavis.net/techblog/" rel="noopener noreferrer"&gt;http://www.jondavis.net/techblog/&lt;/a&gt; runs on a decade old version of BlogEngine.net which I've tailored a bit to include banned IPs and some home-grown CAPTCHA functionality for the comments. I've since looked at a few other blogging engines over the years I've considered adopting, most notably I remember looking at &lt;a href="https://github.com/ChrisFulstow/NBlog" rel="noopener noreferrer"&gt;NBlog&lt;/a&gt;, which gave me the most control but required me to implement it in code and didn't sufficiently demonstrate black box modularity, and &lt;a href="https://ghost.org/" rel="noopener noreferrer"&gt;Ghost&lt;/a&gt;, which would grow me in NodeJS but ticked me off in its stance on only using Markdown and never WYSIWYG HTML editing. Choice would be nice, and non-technical authoring deserves Word-like editing from time to time.&lt;/p&gt;

&lt;p&gt;Meanwhile, the whole time, developers and non-developers alike have pooh-poohed the interestingness of blogs, blogging software, blogging strategies, blogging services, etc. I can certainly see why. At its most basic level, blogs are little more than single-table CRUD apps. You have an index of recent blogs, you have a detail view of an individual blog post, you have an editor and creator page, and you can delete a blog post. The content of a blog post is, to the casual observer, nothing but four components: title, body, author, and publish date. If that's what you think a blog is, you're naive, and likely didn't bother reading this far.&lt;/p&gt;

&lt;p&gt;At the very least, on the technical side, blogging brought about a few innovations that revolutionized the Internet, including: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  XML-RPC (SOAP's midget predecessor)&lt;/li&gt;
&lt;li&gt;  RSS&lt;/li&gt;
&lt;li&gt;  Publish pings&lt;/li&gt;
&lt;li&gt;  Atom&lt;/li&gt;
&lt;li&gt;  OPML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not to mention less specific innovations, like end user accessible management of slugs (URL paths) for enhancing SEO. And the whole notion of blogging became the basis of the World Wide Web's notion of community interconnectivity. The broad set of Web sites &lt;em&gt;was&lt;/em&gt; social networking, before social networks took over social networking. Blog sites were known, and linked to each other. Followers of blogs created view counts that filled the hole that Facebook post likes fill today. &lt;/p&gt;

&lt;p&gt;This is perhaps why &lt;a href="http://dev.to/"&gt;dev.to&lt;/a&gt; is such a success story; it's like a Facebook group, for coders, where every single post is a blog article.&lt;/p&gt;

&lt;p&gt;Anyway, so now I sit here typing into the ten year old deployment of BlogEngine.net on my resurrected tech blog, wondering what my next steps should be. Well, I'm pretty sure I want to create my own blog engine again, and build on it. Yes, it's a two decades stale idea, but here are my motives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  My blog philosophies still differ somewhat from the offerings currently available (although not far at all from BlogEngine.net)&lt;/li&gt;
&lt;li&gt;  I want to keep growing my technical skill set (not just write about them). There are revised web and software standards I need to freshen up on, and apply my learnings. Creating a blog site has always been a good mechanism to sample and apply the most basic web tech skills.&lt;/li&gt;
&lt;li&gt;  I need anything I deploy to a technical blog to portray my own personal portfolio, including the site on which my writings are displayed&lt;/li&gt;
&lt;li&gt;  I still like the idea of taking something I myself created and putting it out on github as a complete package and perhaps managing a hosted instance of it, similar to WordPress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this said, I don't think I'll be doing a full-blown BlogEngine.net equivalence. It will be a simple thing, and from that I'll take some ideas to glean from and apply them to other software efforts I'll be working on. &lt;/p&gt;

&lt;p&gt;But a few things I will point out about the technical strategies and approaches I intend to implement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Rich front-end libs (React, Vue, Blazor, etc)?? While I might take, say, Ghost's approach in having some rich interactivity for the author's experience, the end user (reader) experience cannot be forced to utilize them. A blog page must be rich in HTML semantics and index well SEO-wise for the web at large, so the HTTP response payload cannot be Javascript stub placeholders for dynamic content.&lt;/li&gt;
&lt;li&gt; Componentization is more important than anything else. I do intend to iterate over a lot of the features this old instance of BlogEngine.net has as well as current blog engines, and figure out ways to spoonfeed those features without embedding them deeploy in interdependencies. Worst thing I could do is embed all the bells and whistles directly into ASP.NET Razor Pages themselves. I intend to apply decorator pattern principles, perhaps applying sidecar architecture for some components where appropriate. Right now I'm looking at using Identity Server 4, for example, as a sidecar architecture for author identity and privileges. Speaking of which,&lt;/li&gt;
&lt;li&gt; Everything must be readily run-anywhere, black-box-capable deployable as ad hoc code launched with self-hosting, Azure web app service (PaaS), Docker-contained, or VM (IaaS). I also intend to set up a hosted instance and offer limited blog hosting for free, extended features for a fee. In this sense, WordPress is a competing platform.&lt;/li&gt;
&lt;li&gt; "Extended features, like ..?"  Premium templates. Large storage hosting. And premium add-on features yet to be defined.&lt;/li&gt;
&lt;li&gt; The templates can be based on Razor, but "pages" cannot be tightly defined. If this platform grows up, it needs to be a more than a blog, it needs to be a mini-CMS (content management system).&lt;/li&gt;
&lt;li&gt; Social networking ecosystem is a mandatory consideration; full blogging must integrate with microblogging and multi-contributor cross-pollination including across disparate sites and systems; more on this later, but imagine trusted Twitter users liking Facebook posts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Again, yes, I am unpacking a two decades old solution proposal to a Web 1.0 / 2.0 problem, but that problem never really went away, it just became less prominent. I really don't anticipate this blowing up to being much of anything. At a minimum, I need to convert all of my content here on this technical blog (at &lt;a href="http://www.jondavis.net/techblog/" rel="noopener noreferrer"&gt;http://www.jondavis.net/techblog/&lt;/a&gt;) to a home-grown platform of my own making, even if after doing that I call it done and walk away.&lt;/p&gt;

&lt;p&gt;Another motivator for getting that done is the fact that just writing this, I'm writing with very tiny text on a very high resolution screen, and you're probably squinting reading this, too, if you're reading it from my web site, and if you actually made it this far. Again, yes, I could simply just replace the template and maybe refresh the version of BlogEngine.net which I'm using. But, why do that, when I call myself a 23-years-plus experienced web development veteran and could just build my own? Am I really so useless in my aging as to be unable to build something of my own again? Not like a blog engine will get me a better job, duh, so much as the fact that using someone else's engine just plain looks bad on me. So, this is a lightweight test of mettle. I need to do this because I need to.&lt;/p&gt;

&lt;p&gt;On a final note, I'll mention again what I'm focusing on first: "who am I"--authentication and authorization. I'm learning up on &lt;a href="http://docs.identityserver.io/en/latest/quickstarts/0_overview.html" rel="noopener noreferrer"&gt;Identity Server 4&lt;/a&gt;. I'm still new to it, so this will take some time. Right now it looks like the black box version of my blog engine will come with an instance of Identity Server 4, based perhaps on ASP.NET Core Identity as the user store; developers can tweak it out to their heart's content. I'm still mulling over whether to just embed it into the blog app (underkill? too much in one?) or separate it out as a separate SSO-oriented web app (overkill? too many distributed parts for a mere blog?), but at this point I'll likely do the former for the black box download (source code included) and the latter for the hosted instance which I hope to set up and offer to people wordpress.com-style.&lt;/p&gt;

</description>
      <category>blogging</category>
      <category>blogengine</category>
    </item>
    <item>
      <title>Time to blow off some dust, toot my own horn, and hit the books</title>
      <dc:creator>Jon Davis</dc:creator>
      <pubDate>Tue, 15 Oct 2019 09:36:25 +0000</pubDate>
      <link>https://dev.to/solutionsjon/time-to-blow-off-some-dust-toot-my-own-horn-and-hit-the-books-2243</link>
      <guid>https://dev.to/solutionsjon/time-to-blow-off-some-dust-toot-my-own-horn-and-hit-the-books-2243</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a mirror from my blog post at &lt;a href="http://www.jondavis.net/techblog/" rel="noopener noreferrer"&gt;http://www.jondavis.net/techblog/&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Woah, Nelly!&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Jon Davis's blog is back up! Last post was .. more than three years ago! Daaaang! How ya'll been?! Missed ya'll! Miss me?&lt;/p&gt;

&lt;p&gt;I'm just posting a quick update here to let ya'll know that the gears in my tech world have started turning again, and to update ya'll on what's going on.&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%2Fi.ibb.co%2FR0zsHqz%2Fhomer-bushes.gif%2520%3D250x" 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%2Fi.ibb.co%2FR0zsHqz%2Fhomer-bushes.gif%2520%3D250x" alt="Homer in bushes" width="800" height="400"&gt;&lt;/a&gt;You may or may not have noticed that my root web site &lt;a href="http://jondavis.net/" rel="noopener noreferrer"&gt;http://jondavis.net/&lt;/a&gt; went through a couple phases and got stuck with that dorky "please wait" console-ish page. I was supposed to have replaced it by &lt;em&gt;cough&lt;/em&gt; .. 2016. It's now approaching the year 2020. What happened? Well what happened was I got a few kicks in the pants. Got myself into some really humbling situations, not the fun kind. Perhaps you might say I got phased out of the software dev community. But I never fully left the software dev community, just stayed in the bushes, so now I'm in high gear phasing back in.  I might try to explain ...&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.jondavis.net/techblog/post/2014/01/14/A-Career-Reset.aspx" rel="noopener noreferrer"&gt;A few blog entries ago (this goes back to 2014) I wrote about&lt;/a&gt; how I needed to reset things, and how I needed to mull over what was going on at work. So here's a recap on my career path lately up till my previous job:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In 2012 I was hired at Neudesic, a prominent consultancy firm. I dreamed of surrounding myself with smart people I could glean from. It turned out that things were pretty erratic at Neudesic. My first project assignment the client was Microsoft themselves. Prior to my joining they had just canned a project to build a big, beautiful Windows 8 themed web site where developers and other staff would post all-important articles and index them with Lucene.NET. Architecturally it was a disaster, and they canned the Microsoft executive at the same time they canned the project. So my joining the team, they were trying to salvage that project. I worked with them to try to dig into the code, get it up and running, figure out the performance issues, etc., and at some point I flew out to Redmond, Washington to discuss with the local Neudesic managers who were interfacing with Microsoft in person. Then I opened my mouth. I said, "Ya'll are really just makin' a blog. Why not add blog-ish things? Why reimplement Sharepoint?" Suddenly we were all fired. So then they shipped me off to Pulte Homes, where I did some work there, but the architect for that project and I didn't seem to know what we were doing on the user authorization detail and I proved blunt enough that they "couldn't afford" to keep me on after a couple months. So then they shipped me off to California to work with Ward &amp;amp; Brown on the Obamacare / ACA implementation there, again late to the party and annoyingly insistent to "help". But when QA and I asked around where the production/staging servers were, and they realized they apparently missed that part, they canned all their contractors. All 250 of us. So there I was stuck in the Neudesic-Phoenix office waiting for them to call me in. And they did. They laid me off. Like the child-man that I was, I accidentally let them catch me choking. They did say they might be able to take me back in a few months, though, so ...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the next few months I did some contract work for a local entrepeneur. I waited that out for a while and ultimately I wanted to go back to Neudesic, so ...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In mid-year 2013 I asked Neudesic to take me back in. They did. They brought me back with open arms. It was more awkward for the lot of them than I or anyone anticipated. I'd made myself a reputation for being unrefined up to that point, I'm pretty sure. But anyway, when I arrived (a second time) I noticed that more people, including my former manager, were no longer there. They were laid off too. And I shipped back to Pulte Homes, on another, bigger project. I was up front with them, though, about what specific tools I was unacquainted with, specifically Bootstrap and the like, at the time. They shrugged that off, brought me in anyway. That project was led by--ima be frank here--a really, REALLY bitchy, control freakish, PMS-y woman. I tried to overlook it at the time. I tried to pretend it wasn't so at the time. I'm thinking back half a decade now, and I'm saying it like how I witnessed it. She was horrible. If I ever get in a situation like that again I'll run for the hills. That was awful. She was awful. But anyway, at the time, overlooking that (which I deliberately did), since the lead personality who'd previously been on that project but was laid off was now gone, and I wasn't getting much in the way of introduction, I deliberately, if bombastically, made a ton of assertions and at the same time asked a lot of really stupid, ignorant questions, which ticked off everyone on the team. So they canned me from the team. So that was fun. But what really did me in was I overheard the Neudesic chief developer director guy tell my boss that I "shouldn't be writing software". They assigned me some out-of-state ops role. I should have quit then and there; sure, I screwed up, but I'm a developer, not an ops guy. I didn't last long, and I ultimately did resign.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So now in 2014 I got a very odd and delightfully educational gig with DeMark Analytics. So first of all, Tom DeMark, the owner, is a wealthy financial technician (a term I never knew before) who did what I imagined doing some years back--he studied financial charts and came up with artificially intelligent algorithms that predicted changes in the market. He's one among many people who come up with this stuff, but even so, that's what he did. So now they were building a product for people who could use these financial chart studies--a charting app, basically, with studies being overlaid over the chart. This entailed financial event data being siphoned in to both the back-end engine as well as to the client (the web browser). This is high tech stuff, and the pattern in use was CQRS-ES, which I'd never heard of much less mastered. So here's where it all broke down: 1) We all sat in close proximity to each other. No privacy. All conversations fully exposed. 2) I was hired as a lead, but I was wrong a couple times when I was adament, it was observed by the teammates, and so my authoritative experience as a lead developer was never trusted again. 3) Everyone in the company but maybe four of us was either family to Tom DeMark or close friends of Tom DeMark. It was a nepositic environment. I worked under one of Tom's sons (he was CEO/President), and another of Tom's sons worked under me--well, alongside me, since me being lead didn't work out. He was a bit spoiled. Quick on the Javascript, though, I couldn't keep up with his code, which was charting graphics. Like, at all. So I stopped trying. 4) My pay was adequate (best I can say about it) but my paycheck was cut monthly. Weird, bizarre, and painful. But it was worth it, I was investing in this, I figured. 5) My direct boss was a super high IQ ass. I asked technical questions about the middle/back end from him, like about how Cassandra was to be used, and instead of answering, he'd call everyone over--the CSS front-end developers, everyone. Then ask me to ask my question again. All to I guess humble me? .. Show me that this was "duh" knowledge that everyone would know and understand? So where this went critical was 6) I again used rhetoric. Crap, man. This pretty much got me fired. I used rhetoric! What I mean is, I insinuated, in so many words, that "your explanation sounds vague, and if I didn't know any better I'd say it almost sounds like you said [something obviously stupid]". Except I didn't say it like that, I actually, literally said, ".. you mean [something obviously stupid]?" I really, truly, genuinely &lt;em&gt;trusted&lt;/em&gt; that he understood that I was being rhetorical, but this was the second time I made that mistake--I made the same mistake at Neudesic, "I can't read that [Javascript code]", I could, but I was getting at I shouldn't have to stop and read it--and with these guys it was sabotage. A few minutes later after we returned to our desks he threw his hands up and announced he was switching to Java/Scala. "Sorry Jon." Sorry, Jon? So yeah he was basically saying "you're fired, please quit." It took a couple more months, but I eventually did.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So then I work at another consultancy firm. Solution Stream. Utah-based. They seemed to be trying to spread out into Phoenix. "I can do this," I thought. I learned at Best Software (Sage Software) when I moved to Arizona how consultants--&lt;em&gt;consultants,&lt;/em&gt; not contractors--work, and bring prestige to the process of coming up with technical solutions and strategies, documenting them, and working them with the clients. But Solution Stream was really primarily just interested in creating contractors, apparently, but regardless, they didn't appreciate what I brought to the table, they undersold my capabilities, the executives decided they didn't like me, and they literally pulled me off a project that the client and my direct boss said I was doing great with and signed me over to Banner Health as a temp-to-hire (fire). I had no interest in being hired as a permanent Banner Health employee. When my temp-to-hire contract ended (the "temp-" part), everything ended. I swore off all consulting firms at that point. No more consulting firms. Never again.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So then I got picked up at InEight. Bought out by major construction company Kiewit, InEight was building a cloud version of their Hard Dollar desktop app which manages large scale construction logistics (vendors, materials, supplies, etc). They had some workable plans and ideas. But things broke down real fast. Everyone who interviewed me quit within the year I joined, and it wasn't hard to see why. 1) They had non-technical people at the helm (senior leadership) making some very expensive and frustrating platform and architecture decisions. High performance software with minimal performance hosting, nothing worked, because they didn't want to spend the money for scaling the web tier. 2) The work was outsourced. Most of it was outsourced to India. Eventually they shipped some of it onshore to another midwestern state. But even onshore, most of their staff were H1-B visa holders. Foreigners. Nearly everyone I was working with was from India. Even after so many people quit, I stuck around as long as I could. But eventually I couldn't stand things anymore, my career path had become stagnant, and I knew I couldn't work with the senior executives (no one could, except people from India I guess). I was about to give two weeks notice, when those senior execs pulled me into a room and chewed me out for being "disrespectful". I was done. Never saw them or anyone over there again. &lt;em&gt;(Actually, that's not entirely true; I have maintained strong friendship with at least one colleague from there. He got laid off a few months after I left. We're friends; we literally just met up this week.)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the last year and a half I've been working ... somewhere. For now. I came in as a lead developer, but they, too, openly declared me "disrespectful", so I've given up and just been a highly productive, proficient, heads-down programmer. This place, too, is mostly H1-B visa holders from India. I'm surrounded by foreigners. Scarcely a black, white, or Mexican face. It's depressing. I have less and less each year against Indians but my God, let me work with people of my own culture if I'm here in USA, just a few like-minded, like-raised friends, just a few? And now my team is getting dismantled, due to a third party taking over what we're doing. So I'm about to get laid off. If I'm not laid off, though, well, ... 1) as a contractor, I don't get paid holidays, I don't get paid vacations, and that was painful enough, but unexpectedly after my hire it turns out there is a mandatory two weeks unpaid leave during Christmas &amp;amp; New Year's, and that's unacceptable ($thousands of $dollars lost, not to mention depressing since I spend holidays alone, so yes, it's unacceptable). 2) I have been super comfortable, and super complacent, with little to gain in technical growth. It's been ASP.NET MVC with SQL Server and jQuery. And some .NET Core 2.2 and Razor Pages. Woo wee. &lt;em&gt;sigh&lt;/em&gt; So yeah, I'm open to change, regardless of whether I get laid off.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There's my life story for the last seven years. Stupid, depressing, awful, I've been awful, I've let myself screw myself over time and time again. So here is my new strategy.&lt;/p&gt;

&lt;p&gt;I have no one to blame, even where I've whined and complained, I have no one to blame for my life's frustrations but myself. It's part of the maturing process. I've embraced my learnings and I will carry on. I will try to let go of the past, but I only repeat and document them here because I &lt;em&gt;have&lt;/em&gt; learned from them, and perhaps you can, too. What do I want in my career path? I miss the days when I was an innovator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tooting my horn -- my legacy
&lt;/h2&gt;

&lt;p&gt;You guys remember AJAX? Yeah? I dreamed up AJAX in 1998 when IE4 came out. I called it "TelnetGUI". Stupid name. Other people came up with the same idea a few years later and earned the credit.&lt;/p&gt;

&lt;p&gt;You guys remember Windows Live Writer? Yeah? ... Total rip-off of my PowerBlog app, down to detail. You could say I prototyped Windows Live Writer before Microsoft started working on Windows Live Writer. Microsoft even interviewed me after I built PowerBlog, &lt;em&gt;because&lt;/em&gt; of PowerBlog and its Microsoft-minded inspirations of component integration. Jerk interviewer was like, "Wait, you mean you &lt;em&gt;don't know C++?!&lt;/em&gt; Oh good grief, I thought you were a &lt;em&gt;real&lt;/em&gt; programmer." Screw you, Microsoft interviewer. LOL. Anyway, Windows Live Writer came out a couple years later. Took all of PowerBlog's fundamental ideas, even down to the gleaning the CSS theme and injecting the theme into the editor.&lt;/p&gt;

&lt;p&gt;You guys remember PowerShell? Yeah? I prototyped the idea in or around 2004. I took the ActiveScript COM object, put it in a C++ console container, spoonfed some commands where you could new-up some objects and work with them in a command-line shell, suggested that the sky's the limit if you integrate full-blown .NET CLR and shell commands in this, and showed it to the world on Microsoft's newsgroups. Microsoft was watching; I planted a seed. A year or so later, PowerShell ("Monad") was previewed to the world. I didn't do the dirty work of development of it, but I seeded an idea.&lt;/p&gt;

&lt;p&gt;You guys remember jQuery UI? Yeah? I cobbled together a windowing plugin for jQuery a year or two before jQuery UI was released. It was called &lt;a href="https://github.com/stimpy77/ancient-legacy/tree/master/jqDialogForms" rel="noopener noreferrer"&gt;jqDialogForms&lt;/a&gt;. Pretty nifty, I thought, but heck, I never got to use it in production.  &lt;/p&gt;

&lt;p&gt;In fact there's a lot of crap in my attic I recently dug out and up over at &lt;a href="https://github.com/stimpy77/ancient-legacy" rel="noopener noreferrer"&gt;https://github.com/stimpy77/ancient-legacy&lt;/a&gt;. (It really is crap, nothing much to see.)&lt;/p&gt;

&lt;p&gt;And, oh yeah, you guys remember Entity Framework, Magical Unicorn Edition? I, too, had been inspired by Fluent NHibernate, and I, too, was working on an ORM library I called &lt;a href="https://archive.codeplex.com/?p=gemli" rel="noopener noreferrer"&gt;Gemli&lt;/a&gt; [&lt;a href="https://github.com/stimpy77/gemli" rel="noopener noreferrer"&gt;src&lt;/a&gt;]. Sadly, I ended up with a recursion nightmare I myself stopped being able to read, development slowed to a halt, and then suddenly Microsoft announced that EF Magical Unicorn Edition, and I observed that it did everything I was trying to do in Gemli plus 99x more. So that was a waste of time. Even so, that was mini-ORM-of-my-own-making #2 or #3. &lt;/p&gt;

&lt;p&gt;All of these micro-innovations and others are years old, created during times of passion and egotistical self-perception of brilliance. What happened?! I think we can all see what happened. My ego kept bulldozing my career. My social ineptitude vanquished my opportunities. And I got really, really lazy on the tech side.&lt;/p&gt;

&lt;p&gt;My blog grew stagnant because, frankly, career errors aside, my bold and lengthy philisophical assertions in my blog articles were pretty &lt;em&gt;wrong&lt;/em&gt;. Philosophies like, "&lt;a href="http://www.jondavis.net/techblog/post/2007/09/02/Design-Top-Down-Implement-Bottom-Up.aspx" rel="noopener noreferrer"&gt;design top down, implement bottom up&lt;/a&gt;". Says who? Why? I dunno. Seemed like an interesting case to make at the time. But then people at meetups said they knew my name, read my blog, quoted my article, and I curled up and squealed and said "oh gawd I had no idea what I was writing". (Actually I just nodded my head with a smile and blushed.)&lt;/p&gt;

&lt;p&gt;For the last few weeks I have spent, including study time, more than 70 hours a week, working. Working on hard skills growth. Working on side project development--brainstorming, planning. Working on fixing patchy things, like getting this blog up, so I can get into writing again. It's overdue for a replacement, but frankly I might just switch over to &lt;a href="http://dev.to/"&gt;http://dev.to/&lt;/a&gt; like all the young cool kids.   &lt;strong&gt;&lt;em&gt;OH HAI!!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tech Things I Am Paying Attention To
&lt;/h2&gt;

&lt;p&gt;.NET Core 3 is where it's at, .NET 5 is going to be The Great .NET Redux's great arrival. However, the JVM has had a huge comeback over the last half-decade, and NodeJS and npm like squirrelly cats have been sticking their noses in everything. Big client-side Javascript libraries from a year or two ago (Facebook's React, Google's Angular, China's Vue) are now server-side for some dumb reason. Most importantly, software is becoming event-driven. IaaS is gone. PaaS is passe. Kubernetes is now standard, apparently. Microsoft's MSMQ is so 1990s, RabbitMQ so 00's, LinkedIn's Kafka is apparently where it's at, and now Yahoo!'s Pulsar is gaining noteriety for being even more performant. &lt;/p&gt;

&lt;p&gt;My day job being standard transactional web dev with ASP.NET/jQuery/SQL has made me bewilderingly ansy. If I want to continue to be competitive in complex software architecture and software development I've got to really go knee deep--no, neck deep--in React/Angular/Vue on the front-end, MongoDB, Hadoop, etc on data, Docker/Kubernetes on the platform, Kafka on the data transfer, CQRS+ES on the transaction cycles, DDD as the foundation to argue for it all, and books to explain it all. I need to go to college, and if I don't have time or money for that I need to be studying and reading and challenging myself at all hours I am free until I am confident as a resource for any of these roles.&lt;/p&gt;

&lt;p&gt;Enough of the crap reputation of being a wannabe. Let's be. &lt;/p&gt;

</description>
      <category>career</category>
    </item>
  </channel>
</rss>
