diff --git a/src/Components/Web.JS/@types/dotnet/dotnet.d.ts b/src/Components/Web.JS/@types/dotnet/dotnet.d.ts index 2d0681bedfdf..b421f7de856d 100644 --- a/src/Components/Web.JS/@types/dotnet/dotnet.d.ts +++ b/src/Components/Web.JS/@types/dotnet/dotnet.d.ts @@ -432,4 +432,4 @@ declare global { } declare const createDotnetRuntime: CreateDotnetRuntimeType; -export { AssetEntry, CreateDotnetRuntimeType, DotnetModuleConfig, EmscriptenModule, GlobalizationMode, IMemoryView, ModuleAPI, MonoConfig, ResourceRequest, RuntimeAPI, createDotnetRuntime as default, dotnet, exit }; +export { AssetEntry, CreateDotnetRuntimeType, DotnetHostBuilder, DotnetModuleConfig, EmscriptenModule, GlobalizationMode, IMemoryView, ModuleAPI, MonoConfig, ResourceRequest, RuntimeAPI, createDotnetRuntime as default, dotnet, exit }; diff --git a/src/Components/Web.JS/src/GlobalExports.ts b/src/Components/Web.JS/src/GlobalExports.ts index 73572dfede41..9bedc4132dc9 100644 --- a/src/Components/Web.JS/src/GlobalExports.ts +++ b/src/Components/Web.JS/src/GlobalExports.ts @@ -17,6 +17,7 @@ import { getNextChunk } from './StreamingInterop'; import { RootComponentsFunctions } from './Rendering/JSRootComponents'; import { attachWebRendererInterop } from './Rendering/WebRendererInteropMethods'; import { WebStartOptions } from './Platform/WebStartOptions'; +import { RuntimeAPI } from 'dotnet'; // TODO: It's kind of hard to tell which .NET platform(s) some of these APIs are relevant to. // It's important to know this information when dealing with the possibility of mulitple .NET platforms being available. @@ -38,6 +39,7 @@ interface IBlazor { start?: ((userOptions?: Partial) => Promise) | ((options?: Partial) => Promise) | ((options?: Partial) => Promise); platform?: Platform; rootComponents: typeof RootComponentsFunctions; + runtime: RuntimeAPI, _internal: { navigationManager: typeof navigationManagerInternalFunctions | any; @@ -91,6 +93,7 @@ export const Blazor: IBlazor = { navigateTo, registerCustomEventType, rootComponents: RootComponentsFunctions, + runtime: {} as RuntimeAPI, _internal: { navigationManager: navigationManagerInternalFunctions, diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 5178842558a0..08ae5b377278 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -210,9 +210,25 @@ function prepareRuntimeConfig(options: Partial): Dotnet async function createRuntimeInstance(options: Partial): Promise { const { dotnet } = await importDotnetJs(options); const moduleConfig = prepareRuntimeConfig(options); + + if (options.applicationCulture) { + dotnet.withApplicationCulture(options.applicationCulture); + } + + if (options.environment) { + dotnet.withApplicationEnvironment(options.environment); + } + + if (options.loadBootResource) { + dotnet.withResourceLoader(options.loadBootResource); + } + const anyDotnet = (dotnet as any); + anyDotnet.withModuleConfig(moduleConfig); - anyDotnet.withStartupOptions(options).withModuleConfig(moduleConfig); + if (options.configureRuntime) { + options.configureRuntime(dotnet); + } runtime = await dotnet.create(); const { MONO: mono, BINDING: binding, Module: module, setModuleImports, INTERNAL: mono_internal, getConfig, invokeLibraryInitializers } = runtime; @@ -223,6 +239,7 @@ async function createRuntimeInstance(options: Partial): attachDebuggerHotkey(getConfig()); + Blazor.runtime = runtime; Blazor._internal.dotNetCriticalError = printErr; setModuleImports('blazor-internal', { Blazor: { _internal: Blazor._internal }, diff --git a/src/Components/Web.JS/src/Platform/WebAssemblyStartOptions.ts b/src/Components/Web.JS/src/Platform/WebAssemblyStartOptions.ts index c7ceace25db2..63e8218429f6 100644 --- a/src/Components/Web.JS/src/Platform/WebAssemblyStartOptions.ts +++ b/src/Components/Web.JS/src/Platform/WebAssemblyStartOptions.ts @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +import { DotnetHostBuilder } from 'dotnet'; + export interface WebAssemblyStartOptions { /** * Overrides the built-in boot resource loading mechanism so that boot resources can be fetched @@ -11,7 +13,7 @@ export interface WebAssemblyStartOptions { * @param integrity The integrity string representing the expected content in the response. * @returns A URI string or a Response promise to override the loading process, or null/undefined to allow the default loading behavior. */ - loadBootResource(type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string) : string | Promise | null | undefined; + loadBootResource(type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string): string | Promise | null | undefined; /** * Override built-in environment setting on start. @@ -22,6 +24,11 @@ export interface WebAssemblyStartOptions { * Gets the application culture. This is a name specified in the BCP 47 format. See https://tools.ietf.org/html/bcp47 */ applicationCulture?: string; + + /** + * Allows to override .NET runtime configuration. + */ + configureRuntime(builder: DotnetHostBuilder): void; } // This type doesn't have to align with anything in BootConfig. diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyConfigureRuntimeTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyConfigureRuntimeTest.cs new file mode 100644 index 000000000000..701b81e31c25 --- /dev/null +++ b/src/Components/test/E2ETest/Tests/WebAssemblyConfigureRuntimeTest.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using BasicTestApp; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using OpenQA.Selenium; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETest.Tests; + +public class WebAssemblyConfigureRuntimeTest : ServerTestBase> +{ + public WebAssemblyConfigureRuntimeTest( + BrowserFixture browserFixture, + BlazorWasmTestAppFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + _serverFixture.PathBase = "/subdir"; + } + + protected override void InitializeAsyncCore() + { + base.InitializeAsyncCore(); + + Navigate(ServerPathBase, noReload: false); + Browser.MountTestComponent(); + } + + [Fact] + public void ConfigureRuntimeWorks() + { + var element = Browser.Exists(By.Id("environment")); + Browser.Equal("true", () => element.Text); + } + + [Fact] + public void BlazorRuntimeApiWorks() + { + var element = Browser.Exists(By.Id("build-configuration")); + Browser.Equal("Release", () => element.Text); + } +} diff --git a/src/Components/test/testassets/BasicTestApp/ConfigureRuntime.razor b/src/Components/test/testassets/BasicTestApp/ConfigureRuntime.razor new file mode 100644 index 000000000000..7d1112dc8b73 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/ConfigureRuntime.razor @@ -0,0 +1,19 @@ +@using Microsoft.JSInterop +@inject IJSRuntime JsRuntime + +

+ Environment variable CONFIGURE_RUNTIME: @Environment.GetEnvironmentVariable("CONFIGURE_RUNTIME") +

+

+ .NET runtime build configuration: @RuntimeBuildConfiguration +

+ +@code +{ + protected string RuntimeBuildConfiguration { get; set; } + + protected override async Task OnInitializedAsync() + { + RuntimeBuildConfiguration = await JsRuntime.InvokeAsync("window.getRuntimeBuildConfiguration"); + } +} diff --git a/src/Components/test/testassets/BasicTestApp/Index.razor b/src/Components/test/testassets/BasicTestApp/Index.razor index 97d0bf35d865..6088225c88f5 100644 --- a/src/Components/test/testassets/BasicTestApp/Index.razor +++ b/src/Components/test/testassets/BasicTestApp/Index.razor @@ -14,6 +14,7 @@ + diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html index 9a309622d52c..591c19527b69 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html @@ -48,8 +48,22 @@ function getCurrentUrl() { return location.href; } + + function getRuntimeBuildConfiguration() { + return Blazor.runtime.runtimeBuildInfo.buildConfiguration; + } + + + + -