diff --git a/src/Components/Shared/src/BrowserNavigationManagerInterop.cs b/src/Components/Shared/src/BrowserNavigationManagerInterop.cs index a51bd5720ba2..2f7d4d5c7efd 100644 --- a/src/Components/Shared/src/BrowserNavigationManagerInterop.cs +++ b/src/Components/Shared/src/BrowserNavigationManagerInterop.cs @@ -16,6 +16,8 @@ internal static class BrowserNavigationManagerInterop public const string NavigateTo = Prefix + "navigateTo"; + public const string NavigateToWithArgs = Prefix + "navigateToWithArgs"; + public const string Refresh = Prefix + "refresh"; public const string SetHasLocationChangingListeners = Prefix + "setHasLocationChangingListeners"; diff --git a/src/Components/Web.JS/src/Services/NavigationManager.ts b/src/Components/Web.JS/src/Services/NavigationManager.ts index 36f3e88e2902..57267d2040c9 100644 --- a/src/Components/Web.JS/src/Services/NavigationManager.ts +++ b/src/Components/Web.JS/src/Services/NavigationManager.ts @@ -32,6 +32,7 @@ export const internalFunctions = { setHasLocationChangingListeners, endLocationChanging, navigateTo: navigateToFromDotNet, + navigateToWithArgs: navigateToFromDotNetWithArgs, refresh, getBaseURI: (): string => document.baseURI, getLocationHref: (): string => location.href, @@ -115,6 +116,10 @@ function navigateToFromDotNet(uri: string, options: NavigationOptions): void { navigateToCore(uri, options, /* skipLocationChangingCallback */ true); } +function navigateToFromDotNetWithArgs(uri: string, forceLoad: boolean, replaceHistoryEntry: boolean, historyEntryState: string | null): void { + navigateToCore(uri, { forceLoad, replaceHistoryEntry, historyEntryState: historyEntryState ?? undefined }, /* skipLocationChangingCallback */ true); +} + function navigateToCore(uri: string, options: NavigationOptions, skipLocationChangingCallback = false): void { const absoluteUri = toAbsoluteUri(uri); const pageLoadMechanism = currentPageLoadMechanism(); diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs index 9452c6c33543..58eee4871b1c 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs @@ -341,12 +341,12 @@ internal void InitializeDefaultServices() RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(Services, RenderMode.InteractiveWebAssembly); Services.AddLogging(builder => { - builder.AddProvider(new WebAssemblyConsoleLoggerProvider(DefaultWebAssemblyJSRuntime.Instance)); + builder.AddProvider(new WebAssemblyConsoleLoggerProvider()); }); Services.AddSingleton(); RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(Services, RenderMode.InteractiveWebAssembly); Services.AddSupplyValueFromQueryProvider(); - + // Register metrics and tracing when explicitly enabled (opt-in via feature switch) var isTelemetryEnabled = AppContext.TryGetSwitch("System.Diagnostics.Metrics.Meter.IsSupported", out var switchValue) && switchValue == true; if (isTelemetryEnabled) diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs index c2328cc47dc2..186969184e67 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLogger.cs @@ -5,8 +5,6 @@ using System.Runtime.InteropServices.JavaScript; using System.Text; using Microsoft.Extensions.Logging; -using Microsoft.JSInterop; -using Microsoft.JSInterop.WebAssembly; namespace Microsoft.AspNetCore.Components.WebAssembly.Services; @@ -18,17 +16,15 @@ internal sealed class WebAssemblyConsoleLogger : ILogger, ILogger private static readonly StringBuilder _logBuilder = new StringBuilder(); private readonly string _name; - private readonly WebAssemblyJSRuntime _jsRuntime; - public WebAssemblyConsoleLogger(IJSRuntime jsRuntime) - : this(string.Empty, (WebAssemblyJSRuntime)jsRuntime) // Cast for DI + public WebAssemblyConsoleLogger() + : this(string.Empty) { } - public WebAssemblyConsoleLogger(string name, WebAssemblyJSRuntime jsRuntime) + public WebAssemblyConsoleLogger(string name) { _name = name ?? throw new ArgumentNullException(nameof(name)); - _jsRuntime = jsRuntime ?? throw new ArgumentNullException(nameof(jsRuntime)); } public IDisposable? BeginScope(TState state) where TState : notnull @@ -58,7 +54,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except } } - private void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception? exception) + private static void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception? exception) { lock (_logBuilder) { @@ -93,7 +89,7 @@ private void WriteMessage(LogLevel logLevel, string logName, int eventId, string break; default: // invalid enum values Debug.Assert(logLevel != LogLevel.None, "This method is never called with LogLevel.None."); - _jsRuntime.InvokeVoid("console.log", formattedMessage); + ConsoleLoggerInterop.ConsoleLog(formattedMessage); break; } } @@ -166,6 +162,8 @@ public void Dispose() { } internal static partial class ConsoleLoggerInterop { + [JSImport("globalThis.console.log")] + public static partial void ConsoleLog(string message); [JSImport("globalThis.console.debug")] public static partial void ConsoleDebug(string message); [JSImport("globalThis.console.info")] diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLoggerProvider.cs b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLoggerProvider.cs index 6d4c62213ab0..75f541bca610 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLoggerProvider.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyConsoleLoggerProvider.cs @@ -3,7 +3,6 @@ using System.Collections.Concurrent; using Microsoft.Extensions.Logging; -using Microsoft.JSInterop.WebAssembly; namespace Microsoft.AspNetCore.Components.WebAssembly.Services; @@ -12,22 +11,12 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services; /// internal sealed class WebAssemblyConsoleLoggerProvider : ILoggerProvider { - private readonly ConcurrentDictionary> _loggers; - private readonly WebAssemblyJSRuntime _jsRuntime; - - /// - /// Creates an instance of . - /// - public WebAssemblyConsoleLoggerProvider(WebAssemblyJSRuntime jsRuntime) - { - _loggers = new ConcurrentDictionary>(); - _jsRuntime = jsRuntime; - } + private readonly ConcurrentDictionary> _loggers = new(); /// public ILogger CreateLogger(string name) { - return _loggers.GetOrAdd(name, loggerName => new WebAssemblyConsoleLogger(name, _jsRuntime)); + return _loggers.GetOrAdd(name, static loggerName => new WebAssemblyConsoleLogger(loggerName)); } /// diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyNavigationManager.cs b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyNavigationManager.cs index 401938dbe076..461a0604c2e3 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyNavigationManager.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyNavigationManager.cs @@ -1,11 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices.JavaScript; using Microsoft.AspNetCore.Components.Routing; +using Microsoft.AspNetCore.Components.Web; using Microsoft.Extensions.Logging; -using Microsoft.JSInterop; -using Interop = Microsoft.AspNetCore.Components.Web.BrowserNavigationManagerInterop; namespace Microsoft.AspNetCore.Components.WebAssembly.Services; @@ -49,7 +48,6 @@ public async ValueTask HandleLocationChangingAsync(string uri, string? sta } /// - [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(NavigationOptions))] protected override void NavigateToCore(string uri, NavigationOptions options) { ArgumentNullException.ThrowIfNull(uri); @@ -68,7 +66,7 @@ async Task PerformNavigationAsync() return; } - DefaultWebAssemblyJSRuntime.Instance.InvokeVoid(Interop.NavigateTo, uri, options); + NavigationManagerInterop.NavigateTo(uri, options.ForceLoad, options.ReplaceHistoryEntry, options.HistoryEntryState); } catch (Exception ex) { @@ -82,7 +80,7 @@ async Task PerformNavigationAsync() /// public override void Refresh(bool forceReload = false) { - DefaultWebAssemblyJSRuntime.Instance.InvokeVoid(Interop.Refresh, forceReload); + NavigationManagerInterop.Refresh(forceReload); } protected override void HandleLocationChangingHandlerException(Exception ex, LocationChangingContext context) @@ -102,3 +100,12 @@ private static partial class Log public static partial void NavigationFailed(ILogger logger, string uri, Exception exception); } } + +internal static partial class NavigationManagerInterop +{ + [JSImport(BrowserNavigationManagerInterop.NavigateToWithArgs, "blazor-internal")] + public static partial void NavigateTo(string uri, bool forceLoad, bool replaceHistoryEntry, string? historyEntryState); + + [JSImport(BrowserNavigationManagerInterop.Refresh, "blazor-internal")] + public static partial void Refresh(bool forceReload); +} diff --git a/src/Components/test/testassets/BasicTestApp/PrependMessageLoggerProvider.cs b/src/Components/test/testassets/BasicTestApp/PrependMessageLoggerProvider.cs index e2353a827484..5acdae8626f6 100644 --- a/src/Components/test/testassets/BasicTestApp/PrependMessageLoggerProvider.cs +++ b/src/Components/test/testassets/BasicTestApp/PrependMessageLoggerProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Components.WebAssembly.Services; -using Microsoft.JSInterop; namespace BasicTestApp; @@ -14,10 +13,10 @@ internal class PrependMessageLoggerProvider : ILoggerProvider readonly ILogger _defaultLogger; private bool _disposed = false; - public PrependMessageLoggerProvider(string message, IJSRuntime runtime) + public PrependMessageLoggerProvider(string message) { _message = message; - _defaultLogger = new WebAssemblyConsoleLogger(runtime); + _defaultLogger = new WebAssemblyConsoleLogger(); } public ILogger CreateLogger(string categoryName) diff --git a/src/Components/test/testassets/BasicTestApp/Program.cs b/src/Components/test/testassets/BasicTestApp/Program.cs index 0332b3915c88..ed788f5e62fe 100644 --- a/src/Components/test/testassets/BasicTestApp/Program.cs +++ b/src/Components/test/testassets/BasicTestApp/Program.cs @@ -50,8 +50,8 @@ public static async Task Main(string[] args) builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging")); - builder.Logging.Services.AddSingleton(s => - new PrependMessageLoggerProvider(builder.Configuration["Logging:PrependMessage:Message"], s.GetService())); + builder.Logging.Services.AddSingleton(_ => + new PrependMessageLoggerProvider(builder.Configuration["Logging:PrependMessage:Message"])); var host = builder.Build(); ConfigureCulture(host);