{"title":"Hot Reload Architecture","description":"Understanding the lazy caching and file watching system that powers MyLittleContentEngine\u0027s hot reload functionality","islands":{"content":"\u003Cheader class=\u0022transition-all mb-4 lg:mb-8\u0022\u003E\u003Ch1 class=\u0022font-display text-2xl lg:text-4xl font-bold tracking-tight text-base-900 dark:text-base-50\u0022\u003EHot Reload Architecture\u003C/h1\u003E\u003C/header\u003E\n\n\u003Cmain class=\u0022prose dark:prose-invert dark:text-base-300 max-w-full prose-sm md:prose-base min-w-0 prose-headings:scroll-m-18 prose-headings:font-display prose-headings:text-base-900 dark:prose-headings:text-base-50\u0022\u003E\u003Cp\u003EMyLittleContentEngine provides seamless hot reload functionality during development, allowing content changes to be reflected immediately without restarting the application. This capability is built on two key infrastructure components working together: \u003Cstrong\u003EAsyncLazy\u003C/strong\u003E for thread-safe caching and \u003Cstrong\u003EFileWatchDependencyFactory\u003C/strong\u003E for file system monitoring and cache invalidation.\u003C/p\u003E\n\u003Ch2 id=\u0022architecture-overview\u0022\u003EArchitecture Overview\u003C/h2\u003E\n\u003Cp\u003EAll built-in \u003Ccode\u003EIContentServices\u003C/code\u003E adhere to the hot reload system, which operates on a simple but powerful principle:\u003C/p\u003E\n\u003Col\u003E\n\u003Cli\u003EProcess site wide on reload\u003C/li\u003E\n\u003Cli\u003EProcess page wide on demand\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003EFor example, when you edit a markdown file, it could cause many different things to update beyond just its content:\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003EThe Home Page\u003C/li\u003E\n\u003Cli\u003ESite navigation\u003C/li\u003E\n\u003Cli\u003ETag lists\u003C/li\u003E\n\u003Cli\u003ExRef links\u003C/li\u003E\n\u003Cli\u003ENext/Previous pages\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003EFor example, in the Markdown \u003Ccode\u003EIContentService\u003C/code\u003E, when a change is detected, we reread every Markdown file and parse only the front matter. We\u0027ll defer rendering the Markdown to HTML until the page is actually requested. This gives us two benefits:\u003C/p\u003E\n\u003Col\u003E\n\u003Cli\u003E\u003Cstrong\u003EPerformance\u003C/strong\u003E: Not that Markdig is slow, but between server-side syntax highlighting and Roslyn-connected operations, things can start to add up\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EFull site context\u003C/strong\u003E: Our Markdig extensions and link resolvers have a full site to reference when rendering. This is critical for cross-references and other link rewriting operations.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cdiv class=\u0022code-highlight-wrapper not-prose\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-container\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-highlight\u0022\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022language-mermaid code\u0022\u003E\u003Cspan class=\u0022line\u0022\u003Egraph TB\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    A[File System Changes] --\u0026gt; B[ContentEngineFileWatcher]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    B --\u0026gt; C[FileWatchDependencyFactory.InvalidateInstance]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    C --\u0026gt; D[Debounced Refresh 50ms]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    D --\u0026gt; E[PerformRefreshAsync]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    E --\u0026gt; F[Factory Function Execution]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    F --\u0026gt; G[Cache Update]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    G --\u0026gt; H[Next Request Gets Updated Content]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    I[Blazor Hot Reload] --\u0026gt; J[MetadataUpdateHandler]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    J --\u0026gt; K[ClearCache Called]\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    K --\u0026gt; C\u003C/span\u003E\u003C/code\u003E\u003C/pre\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003Ch2 id=\u0022filewatchdependencyfactory-smart-caching-with-file-invalidation\u0022\u003EFileWatchDependencyFactory: Smart Caching with File Invalidation\u003C/h2\u003E\n\u003Cp\u003EThe \u003Ccode\u003EFileWatchDependencyFactory\u0026lt;T\u0026gt;\u003C/code\u003E class combined with \u003Ccode\u003EAsyncLazy\u0026lt;T\u0026gt;\u003C/code\u003E provides a thread-safe, lazy-loading cache that automatically invalidates when file changes are detected. Services use \u003Ccode\u003EAsyncLazy\u0026lt;T\u0026gt;\u003C/code\u003E for thread-safe initialization while \u003Ccode\u003EAddFileWatched\u0026lt;T\u0026gt;()\u003C/code\u003E registration handles automatic cache invalidation.\u003C/p\u003E\n\u003Cp\u003EFor example, it\u0027s used to cache the results of processing markdown files into a dictionary of content pages. It\u0027s also used in the caching of the MSBuild workspace that drives the Roslyn interactions. This allows these expensive operations to be performed once with the ability to refresh the cache when the underlying files change.\u003C/p\u003E\n\u003Ch3 id=\u0022key-features\u0022\u003EKey Features\u003C/h3\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003ELazy Loading\u003C/strong\u003E: Values are computed only when first accessed\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EThread Safety\u003C/strong\u003E: AsyncLazy provides safe concurrent access from multiple threads\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EAutomatic Invalidation\u003C/strong\u003E: FileWatchDependencyFactory handles cache invalidation on file changes\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EService Integration\u003C/strong\u003E: Integrates seamlessly with DI container service lifetimes\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EAsync-First\u003C/strong\u003E: Built for async operations throughout\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch3 id=\u0022usage-pattern\u0022\u003EUsage Pattern\u003C/h3\u003E\n\u003Cdiv class=\u0022code-highlight-wrapper not-prose\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-container\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-highlight\u0022\u003E\n\u003Cpre\u003E\u003Ccode\u003E\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// Register service with file-watch invalidation (direct registration)\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003Eservices\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAddFileWatched\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentProcessor\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// In service, use AsyncLazy for thread-safe caching\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Eprivate\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Ereadonly\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAsyncLazy\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EConcurrentDictionary\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Estring\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentPage\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-attr roslyn-field-name\u0022\u003E_contentCache\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Epublic\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentService\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentProcessor\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003Eprocessor\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E{\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003E_contentCache\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Enew\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAsyncLazy\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EConcurrentDictionary\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Estring\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentPage\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Easync\u003C/span\u003E \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword---control\u0022\u003Eawait\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003Eprocessor\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EProcessContentFiles\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAsyncLazyFlags\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ERetryOnFailure\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E}\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// Access cached value (computed on first access)\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Evar\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-local-name\u0022\u003Econtent\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword---control\u0022\u003Eawait\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003E_contentCache\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\u003C/code\u003E\u003C/pre\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003Ch3 id=\u0022cache-invalidation\u0022\u003ECache Invalidation\u003C/h3\u003E\n\u003Cp\u003EThe FileWatchDependencyFactory automatically handles cache invalidation when file changes are detected:\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003EImmediate Invalidation\u003C/strong\u003E: Cache is invalidated immediately when files change\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003ELazy Recomputation\u003C/strong\u003E: New values are computed only when next accessed\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EThread Safety\u003C/strong\u003E: Invalidation is thread-safe across multiple concurrent requests\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003EThis eliminates the need for manual debouncing logic while ensuring responsive cache updates during development.\u003C/p\u003E\n\u003Ch2 id=\u0022contentenginefilewatcher-file-system-monitoring\u0022\u003EContentEngineFileWatcher: File System Monitoring\u003C/h2\u003E\n\u003Cp\u003EThe \u003Ccode\u003EContentEngineFileWatcher\u003C/code\u003E monitors specified directories for file changes and triggers refresh operations. It supports both specific file pattern watching and general directory monitoring, with comprehensive integration into Blazor\u0027s hot reload system.\u003C/p\u003E\n\u003Ch3 id=\u0022file-system-watching-features\u0022\u003EFile System Watching Features\u003C/h3\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003EPattern-Based Watching\u003C/strong\u003E: Monitor specific file types (e.g., \u003Ccode\u003E*.md\u003C/code\u003E, \u003Ccode\u003E*.razor\u003C/code\u003E)\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EDirectory Watching\u003C/strong\u003E: Monitor entire directories for any file changes\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003ESubdirectory Support\u003C/strong\u003E: Optionally include subdirectories in watch operations\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EMultiple Event Types\u003C/strong\u003E: Responds to file changes, creation, deletion, and renaming\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EDuplicate Protection\u003C/strong\u003E: Prevents duplicate watchers for the same path/pattern combinations\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch3 id=\u0022blazor-hot-reload-integration\u0022\u003EBlazor Hot Reload Integration\u003C/h3\u003E\n\u003Cp\u003EThe watcher includes special support for Blazor\u0027s hot reload mechanism through the \u003Ca href=\u0022https://learn.microsoft.com/en-us/dotnet/api/system.reflection.metadata.metadataupdatehandlerattribute?view=net-9.0\u0022\u003E\u003Ccode\u003EMetadataUpdateHandler\u003C/code\u003E\u003C/a\u003E attribute:\u003C/p\u003E\n\u003Cdiv class=\u0022code-highlight-wrapper not-prose\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-container\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-highlight\u0022\u003E\n\u003Cpre\u003E\u003Ccode\u003E\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E[\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Eassembly\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMetadataUpdateHandler\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Etypeof\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EContentEngineFileWatcher\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E]\u003C/span\u003E\u003C/span\u003E\u003C/code\u003E\u003C/pre\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\n\u003Cp\u003EThis integration provides:\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003EIDE Integration\u003C/strong\u003E: Works with Visual Studio and VS Code hot reload\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003Edotnet watch Support\u003C/strong\u003E: Automatic refresh when using \u003Ccode\u003Edotnet watch\u003C/code\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EMetadata Updates\u003C/strong\u003E: Responds to C# code changes that affect content processing\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003ECache Clearing\u003C/strong\u003E: Automatically clears content caches when code changes\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch3 id=\u0022watch-types\u0022\u003EWatch Types\u003C/h3\u003E\n\u003Cp\u003EThe file watcher supports two primary watch patterns:\u003C/p\u003E\n\u003Ch4 id=\u00221-specific-file-pattern-watching\u0022\u003E1. Specific File Pattern Watching\u003C/h4\u003E\n\u003Cdiv class=\u0022code-highlight-wrapper not-prose\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-container\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-highlight\u0022\u003E\n\u003Cpre\u003E\u003Ccode\u003E\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// Watch for specific file types with path information\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EfileWatcher\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAddPathWatch\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003Epath\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-string roslyn-string\u0022\u003E\u0022Content/Blog\u0022\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EfilePattern\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-string roslyn-string\u0022\u003E\u0022*.md\u0022\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EonFileChanged\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003EfilePath\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EProcessSpecificFile\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003EfilePath\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EincludeSubdirectories\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Etrue\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\u003C/code\u003E\u003C/pre\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003Ch4 id=\u00222-general-directory-watching\u0022\u003E2. General Directory Watching\u003C/h4\u003E\n\u003Cdiv class=\u0022code-highlight-wrapper not-prose\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-container\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-highlight\u0022\u003E\n\u003Cpre\u003E\u003Ccode\u003E\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// Watch entire directories for any changes\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EfileWatcher\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAddPathsWatch\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003Epaths\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E[\u003C/span\u003E\u003Cspan class=\u0022hljs-string roslyn-string\u0022\u003E\u0022Content\u0022\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003Cspan class=\u0022hljs-string roslyn-string\u0022\u003E\u0022wwwroot\u0022\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E]\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EonUpdate\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ERefreshAllContent\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EincludeSubdirectories\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Etrue\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\u003C/code\u003E\u003C/pre\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003Ch2 id=\u0022integration-in-content-services\u0022\u003EIntegration in Content Services\u003C/h2\u003E\n\u003Cp\u003EThe hot reload architecture is seamlessly integrated into content services. Here\u0027s how it works in practice:\u003C/p\u003E\n\u003Ch3 id=\u0022markdowncontentservice-example\u0022\u003EMarkdownContentService Example\u003C/h3\u003E\n\u003Cdiv class=\u0022code-highlight-wrapper not-prose\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-container\u0022\u003E\n\u003Cdiv class=\u0022standalone-code-highlight\u0022\u003E\n\u003Cpre\u003E\u003Ccode\u003E\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Epublic\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Eclass\u003C/span\u003E \u003Cspan class=\u0022hljs-type roslyn-class-name\u0022\u003EMarkdownContentService\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-type roslyn-type-parameter-name\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E:\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EIMarkdownContentService\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-type roslyn-type-parameter-name\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E{\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Eprivate\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Ereadonly\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAsyncLazy\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EConcurrentDictionary\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Estring\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentPage\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-type roslyn-type-parameter-name\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-attr roslyn-field-name\u0022\u003E_contentCache\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Epublic\u003C/span\u003E \u003Cspan class=\u0022hljs-type roslyn-class-name\u0022\u003EMarkdownContentService\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EContentEngineContentOptions\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-type roslyn-type-parameter-name\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003EengineContentOptions\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EIContentEngineFileWatcher\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003EfileWatcher\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// ... other services\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E{\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// Set up lazy cache with expensive content processing operation\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-attr roslyn-field-name\u0022\u003E_contentCache\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Enew\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAsyncLazy\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EConcurrentDictionary\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Estring\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentPage\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-type roslyn-type-parameter-name\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E            \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Easync\u003C/span\u003E \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword---control\u0022\u003Eawait\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003E_contentProcessor\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EProcessContentFiles\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E,\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E            \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EAsyncLazyFlags\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ERetryOnFailure\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// File watching and cache invalidation is handled by AddFileWatched\u0026lt;T\u0026gt;() registration\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// No need to manually register the service first - AddFileWatched does it all\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E}\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E  \u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Epublic\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Easync\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003ETask\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EMarkdownContentPage\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026lt;\u003C/span\u003E\u003Cspan class=\u0022hljs-type roslyn-type-parameter-name\u0022\u003ETFrontMatter\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E?\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E\u0026gt;\u003C/span\u003E \u003Cspan class=\u0022hljs-function roslyn-method-name\u0022\u003EGetContentPageByUrlOrDefault\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Estring\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003Eurl\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E{\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-keyword roslyn-keyword\u0022\u003Evar\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-local-name\u0022\u003Edata\u003C/span\u003E \u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E=\u003C/span\u003E \u003Cspan class=\u0022hljs-keyword roslyn-keyword---control\u0022\u003Eawait\u003C/span\u003E \u003Cspan class=\u0022hljs-attr roslyn-field-name\u0022\u003E_contentCache\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E \u003Cspan class=\u0022hljs-comment roslyn-comment\u0022\u003E// May trigger recomputation if cache was invalidated\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E        \u003Cspan class=\u0022hljs-keyword roslyn-keyword---control\u0022\u003Ereturn\u003C/span\u003E \u003Cspan class=\u0022hljs-variable roslyn-local-name\u0022\u003Edata\u003C/span\u003E\u003Cspan class=\u0022hljs-operator roslyn-operator\u0022\u003E.\u003C/span\u003E\u003Cspan class=\u0022hljs-function roslyn-identifier\u0022\u003EGetValueOrDefault\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E(\u003C/span\u003E\u003Cspan class=\u0022hljs-variable roslyn-parameter-name\u0022\u003Eurl\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E)\u003C/span\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E;\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E    \u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E}\u003C/span\u003E\u003C/span\u003E\n\u003Cspan class=\u0022line\u0022\u003E\u003Cspan class=\u0022hljs-punctuation roslyn-punctuation\u0022\u003E}\u003C/span\u003E\u003C/span\u003E\u003C/code\u003E\u003C/pre\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003C/div\u003E\n\u003Ch3 id=\u0022workflow\u0022\u003EWorkflow\u003C/h3\u003E\n\u003Col\u003E\n\u003Cli\u003E\u003Cstrong\u003EInitial Load\u003C/strong\u003E: First content access triggers expensive processing operation\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EFile Change\u003C/strong\u003E: Developer modifies a markdown file or source code\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EDetection\u003C/strong\u003E: \u003Ccode\u003EContentEngineFileWatcher\u003C/code\u003E detects the change\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EInvalidation\u003C/strong\u003E: Calls \u003Ccode\u003ENeedsRefresh()\u003C/code\u003E which triggers \u003Ccode\u003E_contentCache.Refresh()\u003C/code\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EDebouncing\u003C/strong\u003E: If multiple changes occur rapidly, they\u0027re coalesced\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EReprocessing\u003C/strong\u003E: After debounce delay, content is reprocessed\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003ECache Update\u003C/strong\u003E: New content replaces cached values\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EUI Refresh\u003C/strong\u003E: Next page request gets updated content\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003EThe hot reload architecture provides a solid foundation for productive development workflows while maintaining excellent performance characteristics through intelligent caching and efficient file system monitoring.\u003C/p\u003E\n\u003C/main\u003E\u003Cdiv class=\u0022flex my-12 border-t border-base-200 dark:border-base-700 pt-4 lg:pt-8\u0022\u003E\u003Cdiv class=\u0022flex flex-col items-start  gap-3\u0022\u003E\u003Ca class=\u0022inline-flex gap-0.5 justify-center overflow-hidden text-sm font-medium font-display transition rounded-xl bg-base-200 pt-1.5 pb-1 px-3 lg:pt-2 lg:pb.15 lg:px-4 hover:bg-base-300/75 dark:bg-base-800/40 text-base-800 dark:text-base-400 ring-1 dark:ring-inset ring-base-300/75 dark:ring-base-800 dark:hover:bg-base-800 dark:hover:text-base-300\u0022 aria-label=\u0022Previous: Development vs Deployment Architecture\u0022 href=\u0022/MyLittleContentEngine/under-the-hood/dev-vs-deployment-architecture/\u0022\u003E\u003Cspan class=\u0022-ml-1 rotate-180\u0022\u003E\u003Csvg viewBox=\u00220 0 20 20\u0022 fill=\u0022none\u0022 aria-hidden=\u0022true\u0022 class=\u0022mt-0.5 h-5 w-5\u0022\u003E\u003Cpath stroke=\u0022currentColor\u0022 stroke-linecap=\u0022round\u0022 stroke-linejoin=\u0022round\u0022 d=\u0022m11.5 6.5 3 3.5m0 0-3 3.5m3-3.5h-9\u0022\u003E\u003C/path\u003E\u003C/svg\u003E\u003C/span\u003E Previous\u003C/a\u003E\n            \u003Ca tabindex=\u0022-1\u0022 aria-hidden=\u0022true\u0022 class=\u0022text-sm lg:text-base font-semibold text-base-700 transition hover:text-base-600 dark:text-base-400 dark:hover:text-base-300\u0022 href=\u0022/MyLittleContentEngine/under-the-hood/dev-vs-deployment-architecture/\u0022\u003EDevelopment vs Deployment Architecture\u003C/a\u003E\u003C/div\u003E\u003Cdiv class=\u0022flex flex-col items-end ml-auto gap-3\u0022\u003E\u003Ca class=\u0022inline-flex gap-0.5 justify-center overflow-hidden text-sm font-medium font-display transition rounded-xl bg-base-200 pt-1.5 pb-1 px-3 lg:pt-2 lg:pb.15 lg:px-4 hover:bg-base-300/75 dark:bg-base-800/40 text-base-800 dark:text-base-400 ring-1 dark:ring-inset ring-base-300/75 dark:ring-base-800 dark:hover:bg-base-800 dark:hover:text-base-300\u0022 aria-label=\u0022Next: Static Site Generation Pipeline\u0022 href=\u0022/MyLittleContentEngine/under-the-hood/content-processing-pipeline/\u0022\u003ENext \u003Cspan class=\u0022-mr-1\u0022\u003E\u003Csvg viewBox=\u00220 0 20 20\u0022 fill=\u0022none\u0022 aria-hidden=\u0022true\u0022 class=\u0022mt-0.5 h-5 w-5\u0022\u003E\u003Cpath stroke=\u0022currentColor\u0022 stroke-linecap=\u0022round\u0022 stroke-linejoin=\u0022round\u0022 d=\u0022m11.5 6.5 3 3.5m0 0-3 3.5m3-3.5h-9\u0022\u003E\u003C/path\u003E\u003C/svg\u003E\u003C/span\u003E\u003C/a\u003E\n            \u003Ca tabindex=\u0022-1\u0022 aria-hidden=\u0022true\u0022 class=\u0022text-sm lg:text-base font-semibold text-base-700 transition hover:text-base-600 dark:text-base-400 dark:hover:text-base-300\u0022 href=\u0022/MyLittleContentEngine/under-the-hood/content-processing-pipeline/\u0022\u003EStatic Site Generation Pipeline\u003C/a\u003E\u003C/div\u003E\u003C/div\u003E"}}