// Internal for testing. internal async Task RunAsyncCore(CancellationToken cancellationToken) { if (_started) { throw new InvalidOperationException("The host has already started."); } _started = true; CultureProvider.ThrowIfCultureChangeIsUnsupported(); // EntryPointInvoker loads satellite assemblies for the application default culture. // Application developers might have configured the culture based on some ambient state // such as local storage, url etc as part of their Program.Main(Async). // This is the earliest opportunity to fetch satellite assemblies for this selection. await CultureProvider.LoadCurrentCultureResourcesAsync(); var tcs = new TaskCompletionSource <object>(); using (cancellationToken.Register(() => { tcs.TrySetResult(null); })) { var loggerFactory = Services.GetRequiredService <ILoggerFactory>(); _renderer = new WebAssemblyRenderer(Services, loggerFactory); var rootComponents = _rootComponents; for (var i = 0; i < rootComponents.Length; i++) { var rootComponent = rootComponents[i]; await _renderer.AddComponentAsync(rootComponent.ComponentType, rootComponent.Selector, rootComponent.Parameters); } await tcs.Task; } }
public static int Add(WebAssemblyRenderer renderer) { var id = _nextId++; _renderers?.Add(id, renderer); return(id); }
public Task StartAsync(CancellationToken cancellationToken = default) { // We need to do this as early as possible, it eliminates a bunch of problems. Note that what we do // is a bit fragile. If you see things breaking because JSRuntime.Current isn't set, then it's likely // that something on the startup path went wrong. // // We want to the JSRuntime created here to be the 'ambient' runtime when JS calls back into .NET. When // this happens in the browser it will be a direct call from Mono. We effectively needs to set the // JSRuntime in the 'root' execution context which implies that we want to do as part of a direct // call from Program.Main, and before any 'awaits'. JSRuntime.SetCurrentJSRuntime(_runtime); SetBrowserHttpMessageHandlerAsDefault(); var scopeFactory = Services.GetRequiredService <IServiceScopeFactory>(); _scope = scopeFactory.CreateScope(); try { var startup = _scope.ServiceProvider.GetService <IBlazorStartup>(); if (startup == null) { var message = $"Could not find a registered Blazor Startup class. " + $"Using {nameof(IWebAssemblyHost)} requires a call to {nameof(IWebAssemblyHostBuilder)}.UseBlazorStartup."; throw new InvalidOperationException(message); } // Note that we differ from the WebHost startup path here by using a 'scope' for the app builder // as well as the Configure method. var builder = new WebAssemblyBlazorApplicationBuilder(_scope.ServiceProvider); startup.Configure(builder, _scope.ServiceProvider); _renderer = builder.CreateRenderer(); } catch { _scope.Dispose(); _scope = null; if (_renderer != null) { _renderer.Dispose(); _renderer = null; } throw; } return(Task.CompletedTask); }
public Task StopAsync(CancellationToken cancellationToken = default) { if (_scope != null) { _scope.Dispose(); _scope = null; } if (_renderer != null) { _renderer.Dispose(); _renderer = null; } return(Task.CompletedTask); }
private async Task StartAsyncAwaited() { var scopeFactory = Services.GetRequiredService <IServiceScopeFactory>(); _scope = scopeFactory.CreateScope(); try { var startup = _scope.ServiceProvider.GetService <IBlazorStartup>(); if (startup == null) { var message = $"Could not find a registered Blazor Startup class. " + $"Using {nameof(IWebAssemblyHost)} requires a call to {nameof(IWebAssemblyHostBuilder)}.UseBlazorStartup."; throw new InvalidOperationException(message); } // Note that we differ from the WebHost startup path here by using a 'scope' for the app builder // as well as the Configure method. var builder = new WebAssemblyBlazorApplicationBuilder(_scope.ServiceProvider); startup.Configure(builder, _scope.ServiceProvider); _renderer = await builder.CreateRendererAsync(); } catch { _scope.Dispose(); _scope = null; if (_renderer != null) { _renderer.Dispose(); _renderer = null; } throw; } }