Native embedding: Consuming ResourceDictionary throws ArgumentNullException on iOS and Android
- Dominant language
- C#
- Stars
- 23.3k
- Forks
- 2k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 296
Description
### Description
In a .NET for iOS/Android app, that uses .NET MAUI native embedding, attempting to consume a `ResourceDictionary` throws an `ArgumentNullException` with the message: Value cannot be null (Parameter 'key').
This doesn't happen on Windows, but at the same time Windows appears to make no effort to consume the RD (iOS + Android at least apply the values in the RD).
```
// Create app-level resource dictionary.
Microsoft.Maui.Controls.Application.Current = new Microsoft.Maui.Controls.Application();
Microsoft.Maui.Controls.Application.Current.Resources = new MyDictionary();
NotesPage notesPage = new NotesPage()
{
// Set the parent so that the app-level resource dictionary can be located.
Parent = Microsoft.Maui.Controls.Application.Current
};
```
Setting the `Parent` was necessary in Xamarin.Forms. The exception is still thrown if `Parent` isn't set.
The stack trace seems to indicate that it's a hot reload issue.
### Steps to Reproduce
1. Run the sample on Android or iOS.
2. After a few seconds the `ArgumentNullException` occurs.
### Link to public reproduction project repository
https://github.com/davidbritch/dotnet-maui-issues/tree/main/Embedding-HotReload
### Version with bug
.NET 7 GA.
### Affected platforms
iOS, Android
### Relevant log output
```shell
Stack trace:
at System.ThrowHelper.ThrowArgumentNullException(String name)
at System.ThrowHelper.ThrowKeyNullException()
at System.Collections.Concurrent.ConcurrentDictionary`2[[Microsoft.Maui.Dispatching.IDispatcher, Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.XamlHotReload.VisualTreeService.VisualTree.DispatcherVisualTreeContext, Microsoft.Maui.Controls.HotReload.Forms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetOrAdd(IDispatcher key, Func`2 valueFactory)
at Microsoft.XamlHotReload.VisualTreeService.VisualTree.VisualTreeContextBase.GetDispatcherContext(IDispatcher dispatcher) in /Users/runner/work/1/s/HotReload/Source/Xamarin.HotReload.Xaml/VisualTreeService/VisualTree/VisualTreeContextBase.cs:line 76
at Microsoft.XamlHotReload.VisualTreeService.VisualTree.FormsVisualTreeContext.<>c__DisplayClass12_0.b__0() in /Users/runner/work/1/s/HotReload/Source/Xamarin.HotReload.Xaml/VisualTreeService/VisualTree/FormsVisualTreeContext.cs:line 58
at Microsoft.XamlHotReload.Utility.DispatcherExtensions.<>c__DisplayClass3_0.b__0() in /Users/runner/work/1/s/HotReload/Source/Microsoft.Maui.Controls.HotReload.Forms/MauiDispatcherExtensions.cs:line 36
at Microsoft.XamlHotReload.Utility.DispatcherExtensions.<>c__DisplayClass4_0`1[[System.Boolean, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].b__1() in /Users/runner/work/1/s/HotReload/Source/Microsoft.Maui.Controls.HotReload.Forms/MauiDispatcherExtensions.cs:line 53
--- End of stack trace from previous location ---
at Microsoft.XamlHotReload.Utility.DispatcherExtensions.Invoke(IDispatcher dispatcher, Action callback) in /Users/runner/work/1/s/HotReload/Source/Microsoft.Maui.Controls.HotReload.Forms/MauiDispatcherExtensions.cs:line 17
at Microsoft.XamlHotReload.VisualTreeService.VisualTree.FormsVisualTreeContext.SubscribeToVisualTreeChanges() in /Users/runner/work/1/s/HotReload/Source/Xamarin.HotReload.Xaml/VisualTreeService/VisualTree/FormsVisualTreeContext.cs:line 57
at Microsoft.XamlHotReload.VisualTreeService.VisualTree.FormsVisualTreeContext.<.ctor>b__2_0(EmptyRequestInfo _) in /Users/runner/work/1/s/HotReload/Source/Xamarin.HotReload.Xaml/VisualTreeService/VisualTree/FormsVisualTreeContext.cs:line 30
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.<>c__DisplayClass34_0`1[[Microsoft.VisualStudio.DesignTools.TapContract.TapOM.EmptyRequestInfo, Microsoft.VisualStudio.DesignTools.TapContract, Version=17.0.0.0, Culture=neutral, PublicKeyToken=null]].b__0(EmptyRequestInfo message)
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.HandleMessage[EmptyRequestInfo,ResponseWithError](Func`2 callback, Message request)
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.<>c__DisplayClass35_0`2[[Microsoft.VisualStudio.DesignTools.TapContract.TapOM.EmptyRequestInfo, Microsoft.VisualStudio.DesignTools.TapContract, Version=17.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.VisualStudio.DesignTools.TapContract.TapOM.ResponseWithError, Microsoft.VisualStudio.DesignTools.TapContract, Version=17.0.0.0, Culture=neutral, PublicKeyToken=null]].b__0(Message message)
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.ProcessInboundMessage(Message message)
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.<>c__DisplayClass48_0.b__0()
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.WaitableActionsList.<>c__DisplayClass8_0.b__0(Boolean isCancelled)
at Microsoft.VisualStudio.DesignTools.TapContract.Networking.ProtocolHandler.ActionThread(Object list)
at System.Threading.Thread.StartCallback()
```
Contributor guide
Research direction
Run the Embedding-HotReload reproduction on Android or iOS, then inspect VisualTreeContextBase.cs line 76, FormsVisualTreeContext.cs lines 30 and 57-58, and MauiDispatcherExtensions.cs lines 17, 36, and 53 from the stack trace. Done means consuming the ResourceDictionary no longer throws ArgumentNullException and its values are applied on the affected platforms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, csharp, ios
- Domain
- mobile-dev, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100