Skip to content

feat(HotReload): IHotReloadAware + MetadataUpdateHandler (aligns with dotnet/maui#35229)#254

Open
StephaneDelcroix wants to merge 8 commits into
mainfrom
feature/hotreload-muh
Open

feat(HotReload): IHotReloadAware + MetadataUpdateHandler (aligns with dotnet/maui#35229)#254
StephaneDelcroix wants to merge 8 commits into
mainfrom
feature/hotreload-muh

Conversation

@StephaneDelcroix
Copy link
Copy Markdown

@StephaneDelcroix StephaneDelcroix commented May 7, 2026

Summary

Adds a new Microsoft.Maui.Labs.HotReload package to maui-labs that wires up [assembly: MetadataUpdateHandler] and exposes a developer-friendly IHotReloadAware interface. Lets any instance — not just views — react when its type is updated by .NET Hot Reload.

This is a maui-labs proving ground for the design tracked by:

Per #35278, the package owns the delivery mechanism (the MetadataUpdateHandler); per #35227, it exposes a developer hook (IHotReloadAware) that any class can implement.

Background

MauiHotReloadHelper.UpdateApplication / ClearCache in Microsoft.Maui.Core have the right shape but the assembly-level [MetadataUpdateHandler] attribute was never added, so the .NET hot reload host never called them. This package fixes that and extends the pattern to any user type via a registry.

What's included

Microsoft.Maui.Labs.HotReload (TFMs: netstandard2.0, net10.0)

Type Purpose
IHotReloadAware Interface with void OnHotReload(Type[]? updatedTypes)
HotReloadRegistry WeakReference-based per-type instance registry
MauiMetadataUpdateHandler The MUH class — calls registry then MauiHotReloadHelper
AssemblyInfo.cs [assembly: MetadataUpdateHandler(...)] (gated to non-netstandard)

The Type[]? updatedTypes argument is forwarded straight from the runtime's MetadataUpdateHandler.UpdateApplication(Type[]?) callback so users see exactly what changed.

The registry uses ref-equality dedup so an instance is never notified twice when both its base type and its own type appear in the updated types list.

Microsoft.Maui.Labs.HotReload.SourceGen (Roslyn incremental generator, netstandard2.0)

For any partial class implementing IHotReloadAware, auto-generates:

private void HotReloadInitialize() => HotReloadRegistry.Register(this);
  • Deduplicates multi-partial-declaration classes (Collect + HashSet)
  • Skips generic and nested types (must register manually)
  • Emits MUH0001 Warning when no constructor calls HotReloadInitialize() (uses a syntax walk, not a substring scan, so comments/docs mentioning the name don't suppress the warning)

Usage

public partial class MyPage : ContentPage, IHotReloadAware
{
    public MyPage()
    {
        InitializeComponent();
        HotReloadInitialize(); // generated by source gen
    }

    public void OnHotReload(Type[]? updatedTypes)
    {
        // refresh viewmodel, reload state, etc.
        // updatedTypes lets you discriminate which type changed
    }
}

Notes

Adds a new Microsoft.Maui.HotReload package providing a proper
[assembly: MetadataUpdateHandler] implementation for .NET MAUI.

## What this adds

### IHotReloadable
A lightweight interface with a single OnHotReload() method. Any class
can implement it to receive a callback when its type is hot-reloaded.

### HotReloadRegistry
A WeakReference-based instance registry. Instances that call
HotReloadRegistry.Register(this) are tracked per-type. When a type is
hot-reloaded, all live instances of that type (and subtypes) are
notified. Ref-equality dedup prevents double-notification when both a
base type and derived type appear in the updated types list.

### MauiMetadataUpdateHandler + AssemblyInfo
The [assembly: MetadataUpdateHandler(typeof(MauiMetadataUpdateHandler))]
attribute wires up the .NET hot reload host so it calls UpdateApplication
and ClearCache automatically. On net10.0+, these delegate to MAUI's
existing MauiHotReloadHelper for view-level reload.

### Microsoft.Maui.HotReload.SourceGen (Roslyn incremental generator)
For partial IHotReloadable classes, auto-generates:
  private void HotReloadInitialize() => HotReloadRegistry.Register(this);

Skips generic types and nested types (register manually).
Emits MUH0001 Info diagnostic when no constructor calls HotReloadInitialize.
Deduplicates multi-partial-declaration classes via Collect() + HashSet.

## Usage
1. Implement IHotReloadable on a partial class
2. Call HotReloadInitialize() in your constructor (source gen reminds you)
3. Override OnHotReload() to respond to hot reload

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 7, 2026 13:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Microsoft.Maui.HotReload NuGet package plus a companion Roslyn incremental source generator (Microsoft.Maui.HotReload.SourceGen) to bridge .NET Hot Reload metadata update notifications into MAUI apps by routing updates to registered IHotReloadable instances (and forwarding to MAUI’s existing hot reload helper on net10.0).

Changes:

  • Introduces Microsoft.Maui.HotReload (netstandard2.0/net10.0) with IHotReloadable, a weak-reference instance registry, and a MetadataUpdateHandler entrypoint.
  • Introduces Microsoft.Maui.HotReload.SourceGen to generate a HotReloadInitialize() registration helper and an informational diagnostic (MUH0001) when it isn’t called.
  • Adds both projects to MauiLabs.slnx.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/HotReload/Microsoft.Maui.HotReload/Microsoft.Maui.HotReload.csproj New shipping package project; multi-targeting and SourceGen analyzer reference.
src/HotReload/Microsoft.Maui.HotReload/MauiMetadataUpdateHandler.cs Metadata update handler that notifies the registry and forwards to MauiHotReloadHelper on non-netstandard TFMs.
src/HotReload/Microsoft.Maui.HotReload/IHotReloadable.cs Public interface for user types to receive hot reload callbacks.
src/HotReload/Microsoft.Maui.HotReload/HotReloadRegistry.cs WeakReference-based registry for instances keyed by runtime type, with update notification dispatch.
src/HotReload/Microsoft.Maui.HotReload/AssemblyInfo.cs Adds [assembly: MetadataUpdateHandler(...)] for non-netstandard builds.
src/HotReload/Microsoft.Maui.HotReload.SourceGen/Microsoft.Maui.HotReload.SourceGen.csproj New Roslyn component project with release-tracking files.
src/HotReload/Microsoft.Maui.HotReload.SourceGen/HotReloadableGenerator.cs Incremental generator emitting HotReloadInitialize() and MUH0001 diagnostic.
src/HotReload/Microsoft.Maui.HotReload.SourceGen/AnalyzerReleases.Unshipped.md Declares the new MUH0001 rule.
src/HotReload/Microsoft.Maui.HotReload.SourceGen/AnalyzerReleases.Shipped.md Initializes shipped analyzer release tracking file.
MauiLabs.slnx Adds the new HotReload projects to the solution.

Comment on lines +128 to +134
string indent = info.Namespace is not null ? " " : string.Empty;
sb.AppendLine($"{indent}partial class {info.ClassName}");
sb.AppendLine($"{indent}{{");
sb.AppendLine($"{indent} /// <summary>Auto-generated. Call from your constructor to register this instance for hot reload notifications.</summary>");
sb.AppendLine($"{indent} private void HotReloadInitialize()");
sb.AppendLine($"{indent} => global::Microsoft.Maui.HotReload.HotReloadRegistry.Register(this);");
sb.AppendLine($"{indent}}}");
Comment on lines +25 to +30
public static void UpdateApplication(Type[] types)
{
HotReloadRegistry.NotifyInstances(types);
#if !NETSTANDARD
MauiHotReloadHelper.UpdateApplication(types);
#endif
Comment on lines +36 to +38
public static void ClearCache(Type[] types)
{
#if !NETSTANDARD
Comment on lines +64 to +67
list.RemoveAt(i);
break;
}
}
@@ -0,0 +1,17 @@
// <auto-generated/>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Expert Code Review — PR #254

Methodology: 3 independent reviewers with adversarial consensus

Summary

7 findings posted as inline comments: 5 moderate, 2 minor

# Severity Consensus File Finding
1 🟡 3/3 HotReloadableGenerator.cs MUH0001 false positive for multi-file partial classes
2 🟡 2/3 HotReloadRegistry.cs Duplicate registration not prevented
3 🟡 2/3 HotReloadRegistry.cs OnHotReload() invoked on background thread (no UI dispatch)
4 🟡 follow-up validated HotReloadableGenerator.cs Generator not truly incremental (no equality, Location in model)
5 🟡 follow-up 2/3 (disputed) Microsoft.Maui.HotReload.csproj Source generator may not ship in NuGet package
6 🟢 2/3 HotReloadRegistry.cs Dead WeakReference entries accumulate in NotifyInstances
7 🟢 follow-up 2/3 (disputed) HotReloadRegistry.cs NotifyInstances lacks null guard

Discarded findings (single reviewer, no consensus)

  • // <auto-generated/> header on hand-written IHotReloadable.cs (Reviewer 2 only, 🟢)
  • No CI workflow or solution filter for new product (Reviewer 2 only, 🟢)
  • _registry dictionary entries never pruned when empty (Reviewer 2 only, 🟢)
  • Missing PrivateAssets="all" on SourceGen ProjectReference (Reviewer 1 only, 🟢)

CI Status

CI is in progress — license/cla ✅, Prepare ✅, Agent ✅, Upload results ✅, Cleanup artifacts 🔄, agent (this review) 🔄. No product-specific CI workflow exists for the HotReload product yet.

Test Coverage

⚠️ No tests included. This PR introduces a new shipped package with IsShipping=true but does not include a test project. Per repo conventions, a test project (src/HotReload/Microsoft.Maui.HotReload.Tests/) covering the registry, notification logic, and source generator output is expected.

Generated by Expert Code Review · 3 independent reviewers with adversarial consensus

Warning

⚠️ Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • learn.microsoft.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "learn.microsoft.com"

See Network Configuration for more information.

Generated by Expert Code Review (auto) for issue #254 · ● 11.1M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expert Code Review: 7 findings posted inline (5 moderate, 2 minor). See the lean summary comment for full details.

Warning

⚠️ Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • learn.microsoft.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "learn.microsoft.com"

See Network Configuration for more information.

Generated by Expert Code Review (auto) for issue #254 · ● 11.1M

Comment on lines +103 to +111
{
var seen = new System.Collections.Generic.HashSet<string>(StringComparer.Ordinal);
foreach (var info in allCandidates)
{
// Only emit once per unique class (multiple partial declarations yield the same HintName).
if (!seen.Add(info.HintName))
continue;

EmitSource(ctx, info);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MODERATE · 3/3 consensus

MUH0001 false positive for multi-file partial classes. When a class is split across partial files (e.g., MyPage.xaml.cs with the constructor and MyPage.xaml.g.cs without), EmitAllSources picks whichever candidate appears first via seen.Add(). If the partial without a constructor is processed first, HasInitCall is false and MUH0001 fires — even though another partial file correctly calls HotReloadInitialize().

Scenario: Any XAML-backed page implementing IHotReloadable where the constructor lives in the code-behind will get a spurious diagnostic.

Fix: Merge HasInitCall across all candidates sharing the same HintName before emitting the diagnostic:

// In EmitAllSources, aggregate HasInitCall with OR across duplicates
var merged = new Dictionary<string, HotReloadableClassInfo>(StringComparer.Ordinal);
foreach (var info in allCandidates)
{
    if (merged.TryGetValue(info.HintName, out var existing))
    {
        if (info.HasInitCall && !existing.HasInitCall)
            merged[info.HintName] = new(..., hasInitCall: true);
    }
    else merged[info.HintName] = info;
}

Comment on lines +33 to +35
<ProjectReference Include="..\Microsoft.Maui.HotReload.SourceGen\Microsoft.Maui.HotReload.SourceGen.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MODERATE · validated via follow-up (disputed: 2/3 agreed, 1 disagreed)

Source generator may not ship in NuGet package. One reviewer noted that OutputItemType="Analyzer" on a ProjectReference may not automatically pack the generator DLL into analyzers/dotnet/cs/ in the .nupkg — particularly with Arcade SDK pack targets. If so, consumers would get the runtime library but no source generator, making HotReloadInitialize() unavailable.

Note: This is disputed — the standard .NET SDK does flow OutputItemType="Analyzer" ProjectReferences into the package during pack. However, it's worth verifying with a dotnet pack and inspecting the output .nupkg to confirm the analyzer DLL is present. If not, add explicit pack items:

<None Include="$(OutputPath)\..\Microsoft.Maui.HotReload.SourceGen\**\*.dll"
      Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

/// Notifies all registered instances whose runtime type is, or derives from, any of the
/// <paramref name="updatedTypes"/>. Called by <see cref="MauiMetadataUpdateHandler"/>.
/// </summary>
internal static void NotifyInstances(Type[] updatedTypes)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 MINOR · validated via follow-up (disputed: 2/3 agreed, 1 disagreed)

NotifyInstances lacks null guard. While the .NET runtime is unlikely to pass null to MetadataUpdateHandler methods in practice, adding a defensive check is low-cost and prevents an NRE from propagating to the hot reload host if invoked from a non-standard caller or test harness.

Fix:

internal static void NotifyInstances(Type[] updatedTypes)
{
    if (updatedTypes is null || updatedTypes.Length == 0)
        return;
    // ...
}

Comment on lines +89 to +92
foreach (var weakRef in kvp.Value)
{
if (!weakRef.TryGetTarget(out var instance))
continue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 MINOR · 2/3 consensus

Dead WeakReference entries accumulate in NotifyInstances. When iterating kvp.Value, dead references are skipped (continue) but never removed. Cleanup only happens when a new instance of the same type calls Register(). For types created once at startup (singletons, app-level pages), dead refs from prior instances accumulate permanently.

Fix: Opportunistically compact after building toNotify, or collect dead indices during iteration and remove them under the same lock pass.

Comment on lines +150 to +166
sealed class HotReloadableClassInfo
{
public string? Namespace { get; }
public string ClassName { get; }
public string HintName { get; }
public Location Location { get; }
public bool HasInitCall { get; }

public HotReloadableClassInfo(string? ns, string className, string hintName, Location location, bool hasInitCall)
{
Namespace = ns;
ClassName = className;
HintName = hintName;
Location = location;
HasInitCall = hasInitCall;
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MODERATE · validated via follow-up (2/2 agreed)

Incremental generator not truly incremental. HotReloadableClassInfo lacks Equals/GetHashCode overrides, so Roslyn's incremental pipeline uses reference equality — which always fails for newly created instances. Combined with storing Location (which changes across compilations even without source changes), the EmitAllSources callback re-fires unnecessarily on every compilation pass where any IHotReloadable file is touched.

Impact: In a MAUI project with many pages, this causes constant re-emission of all generated files during IDE editing, defeating the incremental generator's caching.

Fix: Make HotReloadableClassInfo a record (or implement IEquatable<T>) with value equality on Namespace, ClassName, HintName, and HasInitCall. Move Location out of the cached model into a separate pipeline for diagnostic reporting.

Comment on lines +116 to +120
foreach (var instance in toNotify)
{
try
{
instance.OnHotReload();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MODERATE · 2/3 consensus

OnHotReload() invoked on background thread. The .NET hot reload host calls MetadataUpdateHandler methods on a non-UI thread. Realistic OnHotReload() implementations will update UI (rebind ViewModels, set properties on views), which will throw platform threading exceptions (UIKitThreadAccessException on iOS, CalledFromWrongThreadException on Android).

Note: MauiHotReloadHelper.UpdateApplication (called afterward) dispatches internally, but NotifyInstances does not.

Fix: Either dispatch to the UI thread before invoking callbacks:

Microsoft.Maui.ApplicationModel.MainThread.BeginInvokeOnMainThread(() =>
{
    foreach (var instance in toNotify)
        instance.OnHotReload();
});

Or clearly document in IHotReloadable.OnHotReload() that implementations must self-dispatch to the main thread.


// Compact dead references before adding to keep the list small.
list.RemoveAll(static w => !w.TryGetTarget(out _));
list.Add(new WeakReference<IHotReloadable>(instance));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MODERATE · 2/3 consensus

Duplicate registration not prevented. Register() compacts dead references but never checks for an existing live reference to the same instance. If HotReloadInitialize() is called more than once (e.g., from both a base-class and derived-class constructor, or on page re-use), the same instance is added multiple times. Each subsequent NotifyInstances call will invoke OnHotReload() N times on that instance.

Scenario: Base class constructor calls HotReloadInitialize(), derived class also calls it → double notification on every hot reload.

Fix: Before appending, scan for the instance:

list.RemoveAll(static w => !w.TryGetTarget(out _));
// Add dedup check:
foreach (var wr in list)
    if (wr.TryGetTarget(out var existing) && ReferenceEquals(existing, instance))
        return;
list.Add(new WeakReference<IHotReloadable>(instance));

- Solution filter: src/HotReload/HotReload.slnf
- CI workflow: .github/workflows/ci-hotreload.yml (uses _build.yml)
- Product README: src/HotReload/README.md
- AzDO pipeline: build job + publish stage in devflow-official.yml
- Root README: HotReload product listing
- AGENTS.md: HotReload product entry and project layout

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Redth
Copy link
Copy Markdown
Member

Redth commented May 8, 2026

@StephaneDelcroix we had talked about maybe having some parameter on the method to help differentiate between "xaml hot reload took care of everything" reloads and others?

StephaneDelcroix and others added 4 commits May 12, 2026 08:36
Avoids future conflicts with a potential Microsoft.Maui.HotReload
package shipping from the main dotnet/maui repository.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Without this, the SourceGen DLL was not embedded in the package and
HotReloadInitialize() would not be generated for consumers.

Uses MSBuild GetTargetPath to locate the DLL regardless of build
artifacts layout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use versioned NuGet path (roslyn4.0/cs/) instead of generic analyzers/dotnet/cs/
  because .NET 10+ SDK sets SupportsRoslynComponentVersioning=true, which causes it
  to ignore the generic path entirely.

- Pin Roslyn reference to 4.4.0 (CLR 4.4.0.0), matching what
  Microsoft.Extensions.Options.SourceGeneration does. The Roslyn AnalyzerAssemblyLoader
  redirects these references to the host Roslyn version at runtime, so 4.4.0.0 works
  with Roslyn 5.x SDKs (SDK 10 and SDK 11). Using 5.x was wrong because the loader
  does not redirect across major versions in preview SDKs.

- Remove debug canary (RegisterPostInitializationOutput emitting Canary.g.cs).

Verified: generator produces HotReloadInitialize() for classes implementing
IHotReloadable on both SDK 10 (net10.0) and SDK 11 (net11.0-android).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…alize call

- Bump severity from Info to Warning so the diagnostic is visible in CLI builds
  (Info-level diagnostics are only surfaced by IDEs).
- Replace the substring check on the constructor body text with a SyntaxWalk over
  IdentifierNameSyntax descendants. The previous check would treat a comment that
  merely mentioned 'HotReloadInitialize' as a real call, suppressing the warning
  when it should have fired.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@jfversluis jfversluis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build errors

… types

Aligns the API surface with the design tracked in:
  dotnet/maui#35229 (Hot Reload Developer Experience epic)
  dotnet/maui#35227 (Design IHotReloadAware interface)
  dotnet/maui#35278 (Framework MetadataUpdateHandler)

API changes:
- Rename interface IHotReloadable -> IHotReloadAware
- Change OnHotReload() -> OnHotReload(Type[]? updatedTypes), forwarding the same
  type info the runtime passes to MetadataUpdateHandler.UpdateApplication
- Rename source file IHotReloadable.cs -> IHotReloadAware.cs
- Rename generator file/class HotReloadableGenerator -> HotReloadAwareGenerator
- Update MUH0001 diagnostic messages and generator type lookup accordingly

Drive-by fix:
- The net10.0 build of MauiMetadataUpdateHandler was silently broken because
  MauiHotReloadHelper lives in Microsoft.Maui.HotReload, which is a sibling (not
  ancestor) namespace of Microsoft.Maui.Labs.HotReload — C# parent-namespace
  lookup never resolved it. Add 'using Microsoft.Maui.HotReload;' inside the
  existing #if !NETSTANDARD block. The netstandard2.0 ref-assembly that ships
  was unaffected, so this was latent.

Verified: gen-smoke project (SDK 10) emits HotReloadInitialize() for IHotReloadAware
classes, MUH0001 fires when constructor doesn't call it, OnHotReload(Type[]?)
signature compiles cleanly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@StephaneDelcroix StephaneDelcroix changed the title feat: add Microsoft.Maui.HotReload package feat(HotReload): IHotReloadAware + MetadataUpdateHandler (aligns with dotnet/maui#35229) May 13, 2026
Copy link
Copy Markdown
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got this to work with dotnet watch in .NET 11 Preview 4:

Image

But I had to do this:

public partial class MainPage : ContentPage, IHotReloadAware
{
	public MainPage()
	{
		InitializeComponent();
		HotReloadInitialize(); // generated by MUH source generator
	}

	public void OnHotReload(Type[]? updatedTypes)
	{
		System.Diagnostics.Debug.WriteLine("MainPage was hot-reloaded!");
		Device.BeginInvokeOnMainThread(() =>
		{
			// Re-initialize the page to pick up any changes to XAML or code.
			InitializeComponent();
		});
	}

I also had to remove the x:Name on the page, or I got an exception.

Am I using it right?

@drasticactions
Copy link
Copy Markdown

Running it on Avalonia.Controls.Maui and Peppers change above, it worked out of the box for me with our default TFM and Avalonia handlers,

スクリーンショット 2026-05-15 15 22 47

At least with the basic smoke test template.

I did get an exception running it on Catalyst both in this sandbox and in a standalone new MAUI template, at least on net11.0-maccatalyst

Unhandled exception. System.ArgumentException: Startup hook assembly '/Users/da/.dotnet/sdk/11.0.100-preview.4.26230.115/DotnetTools/dotnet-watch/11.0.100-preview.4.26230.115/tools/net11.0/any/hotreload/net10.0/Microsoft.Extensions.DotNetDeltaApplier.dll' failed to load. See inner exception for details.
 ---> System.IO.FileLoadException: Could not load file or assembly '/Users/da/.dotnet/sdk/11.0.100-preview.4.26230.115/DotnetTools/dotnet-watch/11.0.100-preview.4.26230.115/tools/net11.0/any/hotreload/net10.0/Microsoft.Extensions.DotNetDeltaApplier.dll'. Access is denied.

File name: '/Users/da/.dotnet/sdk/11.0.100-preview.4.26230.115/DotnetTools/dotnet-watch/11.0.100-preview.4.26230.115/tools/net11.0/any/hotreload/net10.0/Microsoft.Extensions.DotNetDeltaApplier.dll'
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyBinder, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
   --- End of inner exception stack trace ---
   at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
   at System.StartupHookProvider.ProcessStartupHooks(String diagnosticStartupHooks)
   at System.StartupHookProvider.ManagedStartup(Char* pDiagnosticStartupHooks, Exception* pException)

Note that it is located in my local dotnet folder. The dll is there and it should have permissions to access it (It works fine with the default TFM) so I'm not sure why it's failing. But that's an SDK issue I think.

@jfversluis
Copy link
Copy Markdown
Member

@copilot resolve the merge conflicts in this pull request

Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 24, 2026

@copilot resolve the merge conflicts in this pull request

Resolved the merge conflicts by merging origin/main into this branch and fixing the AGENTS.md conflict. Commit: 277f2be.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 0t3vsblobprodcus362.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build src/HotReload/HotReload.slnf (dns block)
  • 1p7vsblobprodcus324.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build src/HotReload/HotReload.slnf (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from jfversluis May 24, 2026 16:10
davidortinau added a commit to davidortinau/BaristaNotes that referenced this pull request May 27, 2026
Adds IHotReloadAware integration on BaristaApp and ThemeService for use
with .NET 11 Preview 4 'dotnet watch'.

- Add Debug-only PackageReference to Microsoft.Maui.Labs.HotReload 0.1.0-dev
  (from local feed; built from dotnet/maui-labs#254).
- ThemeService: partial class, HotReloadInitialize() called from ctor,
  OnHotReload logs updated types via ILogger.
- BaristaApp: partial class implementing IHotReloadAware. MauiReactor's
  ComponentPartialClassSourceGenerator already emits the parameterless
  ctor, so HotReloadInitialize() is invoked from OnMounted instead.
  MUH0001 is suppressed at the class declaration because the labs source
  generator only walks constructors.
- OnHotReload calls Invalidate() on the component to force a re-render.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants