/// <summary> /// Sets the current <see cref="Circuits.Circuit"/>. /// </summary> /// <param name="circuitHost">The <see cref="Circuits.Circuit"/>.</param> /// <remarks> /// Calling <see cref="SetCurrentCircuitHost(CircuitHost)"/> will store the circuit /// and other related values such as the <see cref="IJSRuntime"/> and <see cref="Renderer"/> /// in the local execution context. Application code should not need to call this method, /// it is primarily used by the Server-Side Components infrastructure. /// </remarks> public static void SetCurrentCircuitHost(CircuitHost circuitHost) { _current.Value = circuitHost ?? throw new ArgumentNullException(nameof(circuitHost)); Microsoft.JSInterop.JSRuntime.SetCurrentJSRuntime(circuitHost.JSRuntime); RendererRegistry.SetCurrentRendererRegistry(circuitHost.RendererRegistry); }
public override CircuitHost CreateCircuitHost(HttpContext httpContext, IClientProxy client) { if (!_options.StartupActions.TryGetValue(httpContext.Request.Path, out var config)) { var message = $"Could not find an ASP.NET Core Components startup action for request path '{httpContext.Request.Path}'."; throw new InvalidOperationException(message); } var scope = _scopeFactory.CreateScope(); var jsRuntime = new RemoteJSRuntime(client); var rendererRegistry = new RendererRegistry(); var synchronizationContext = new CircuitSynchronizationContext(); var renderer = new RemoteRenderer(scope.ServiceProvider, rendererRegistry, jsRuntime, client, synchronizationContext); var circuitHandlers = scope.ServiceProvider.GetServices <CircuitHandler>() .OrderBy(h => h.Order) .ToArray(); var circuitHost = new CircuitHost( scope, client, rendererRegistry, renderer, config, jsRuntime, synchronizationContext, circuitHandlers); // Initialize per-circuit data that services need (circuitHost.Services.GetRequiredService <IJSRuntimeAccessor>() as DefaultJSRuntimeAccessor).JSRuntime = jsRuntime; (circuitHost.Services.GetRequiredService <ICircuitAccessor>() as DefaultCircuitAccessor).Circuit = circuitHost.Circuit; return(circuitHost); }
public void Dispose_DisposesResources() { // Arrange var serviceScope = new Mock <IServiceScope>(); var clientProxy = Mock.Of <IClientProxy>(); var renderRegistry = new RendererRegistry(); var jsRuntime = Mock.Of <IJSRuntime>(); var syncContext = new CircuitSynchronizationContext(); var remoteRenderer = new TestRemoteRenderer( Mock.Of <IServiceProvider>(), renderRegistry, jsRuntime, clientProxy, syncContext); var circuitHost = new CircuitHost(serviceScope.Object, clientProxy, renderRegistry, remoteRenderer, configure: _ => { }, jsRuntime: jsRuntime, synchronizationContext: syncContext); // Act circuitHost.Dispose(); // Assert serviceScope.Verify(s => s.Dispose(), Times.Once()); Assert.True(remoteRenderer.Disposed); }
/// <summary> /// Registers an active <see cref="CircuitHost"/> with the register. /// </summary> public void Register(CircuitHost circuitHost) { if (!ConnectedCircuits.TryAdd(circuitHost.CircuitId, circuitHost)) { // This will likely never happen, except perhaps in unit tests, since CircuitIds are unique. throw new ArgumentException($"Circuit with identity {circuitHost.CircuitId} is already registered."); } }
public void PermanentDisconnect(CircuitHost circuitHost) { if (ConnectedCircuits.TryRemove(circuitHost.CircuitId, out _)) { Log.CircuitDisconnectedPermanently(_logger, circuitHost.CircuitId); circuitHost.Client.SetDisconnected(); } }
public override CircuitHost CreateCircuitHost( HttpContext httpContext, CircuitClientProxy client, string uriAbsolute, string baseUriAbsolute) { var components = ResolveComponentMetadata(httpContext, client); var scope = _scopeFactory.CreateScope(); var encoder = scope.ServiceProvider.GetRequiredService <HtmlEncoder>(); var jsRuntime = (RemoteJSRuntime)scope.ServiceProvider.GetRequiredService <IJSRuntime>(); var componentContext = (RemoteComponentContext)scope.ServiceProvider.GetRequiredService <IComponentContext>(); jsRuntime.Initialize(client); componentContext.Initialize(client); var uriHelper = (RemoteUriHelper)scope.ServiceProvider.GetRequiredService <IUriHelper>(); if (client != CircuitClientProxy.OfflineClient) { uriHelper.Initialize(uriAbsolute, baseUriAbsolute, jsRuntime); } else { uriHelper.Initialize(uriAbsolute, baseUriAbsolute); } var rendererRegistry = new RendererRegistry(); var dispatcher = Renderer.CreateDefaultDispatcher(); var renderer = new RemoteRenderer( scope.ServiceProvider, rendererRegistry, jsRuntime, client, dispatcher, encoder, _loggerFactory.CreateLogger <RemoteRenderer>()); var circuitHandlers = scope.ServiceProvider.GetServices <CircuitHandler>() .OrderBy(h => h.Order) .ToArray(); var circuitHost = new CircuitHost( scope, client, rendererRegistry, renderer, components, dispatcher, jsRuntime, circuitHandlers, _loggerFactory.CreateLogger <CircuitHost>()); // Initialize per - circuit data that services need (circuitHost.Services.GetRequiredService <ICircuitAccessor>() as DefaultCircuitAccessor).Circuit = circuitHost.Circuit; return(circuitHost); }
public CircuitHost CreateCircuitHost( IReadOnlyList <ComponentDescriptor> components, CircuitClientProxy client, string baseUri, string uri, ClaimsPrincipal user) { var scope = _scopeFactory.CreateScope(); var jsRuntime = (RemoteJSRuntime)scope.ServiceProvider.GetRequiredService <IJSRuntime>(); jsRuntime.Initialize(client); var navigationManager = (RemoteNavigationManager)scope.ServiceProvider.GetRequiredService <NavigationManager>(); var navigationInterception = (RemoteNavigationInterception)scope.ServiceProvider.GetRequiredService <INavigationInterception>(); if (client.Connected) { navigationManager.AttachJsRuntime(jsRuntime); navigationManager.Initialize(baseUri, uri); navigationInterception.AttachJSRuntime(jsRuntime); } else { navigationManager.Initialize(baseUri, uri); } var renderer = new RemoteRenderer( scope.ServiceProvider, _loggerFactory, _options, client, _loggerFactory.CreateLogger <RemoteRenderer>(), jsRuntime.ElementReferenceContext); var circuitHandlers = scope.ServiceProvider.GetServices <CircuitHandler>() .OrderBy(h => h.Order) .ToArray(); var circuitHost = new CircuitHost( _circuitIdFactory.CreateCircuitId(), scope, _options, client, renderer, components, jsRuntime, circuitHandlers, _loggerFactory.CreateLogger <CircuitHost>()); Log.CreatedCircuit(_logger, circuitHost); // Initialize per - circuit data that services need (circuitHost.Services.GetRequiredService <ICircuitAccessor>() as DefaultCircuitAccessor).Circuit = circuitHost.Circuit; circuitHost.SetCircuitUser(user); return(circuitHost); }
/// <summary> /// Sets the current <see cref="Circuits.Circuit"/>. /// </summary> /// <param name="circuitHost">The <see cref="Circuits.Circuit"/>.</param> /// <remarks> /// Calling <see cref="SetCurrentCircuitHost(CircuitHost)"/> will store related values such as the /// <see cref="IJSRuntime"/> and <see cref="Renderer"/> /// in the local execution context. Application code should not need to call this method, /// it is primarily used by the Server-Side Components infrastructure. /// </remarks> public static void SetCurrentCircuitHost(CircuitHost circuitHost) { if (circuitHost is null) { throw new ArgumentNullException(nameof(circuitHost)); } JSInterop.JSRuntime.SetCurrentJSRuntime(circuitHost.JSRuntime); }
public virtual Task DisconnectAsync(CircuitHost circuitHost, string connectionId) { Task circuitHandlerTask; lock (CircuitRegistryLock) { if (DisconnectCore(circuitHost, connectionId)) { circuitHandlerTask = circuitHost.Dispatcher.InvokeAsync(() => circuitHost.OnConnectionDownAsync(default));
protected override bool DisconnectCore(CircuitHost circuitHost, string connectionId) { if (BeforeDisconnect != null) { Assert.True(BeforeDisconnect?.Wait(TimeSpan.FromSeconds(10)), "BeforeDisconnect failed to be set"); } return(base.DisconnectCore(circuitHost, connectionId)); }
internal static void CreatedCircuit(ILogger logger, CircuitHost circuitHost) { if (circuitHost.Client.Connected) { _createdConnectedCircuit(logger, circuitHost.CircuitId, circuitHost.Client.ConnectionId, null); } else { _createdDisconnectedCircuit(logger, circuitHost.CircuitId, null); } }
public virtual Task DisconnectAsync(CircuitHost circuitHost, string connectionId) { Log.CircuitDisconnectStarted(_logger, circuitHost.CircuitId, connectionId); Task circuitHandlerTask; lock (CircuitRegistryLock) { if (DisconnectCore(circuitHost, connectionId)) { circuitHandlerTask = circuitHost.Renderer.Dispatcher.InvokeAsync(() => circuitHost.OnConnectionDownAsync(default));
/// <summary> /// Registers an active <see cref="CircuitHost"/> with the register. /// </summary> public void Register(CircuitHost circuitHost) { if (!ConnectedCircuits.TryAdd(circuitHost.CircuitId, circuitHost)) { // This will likely never happen, except perhaps in unit tests, since CircuitIds are unique. throw new ArgumentException($"Circuit with identity {circuitHost.CircuitId} is already registered."); } // Register for unhandled exceptions from the circuit. The registry is responsible for tearing // down the circuit on errors. circuitHost.UnhandledException += CircuitHost_UnhandledException; }
private static async Task CleanupCircuitState(HttpContext context, CircuitNavigationStatus navigationStatus, CircuitHost circuitHost) { navigationStatus.Navigated = true; context.Items.Remove(CircuitHostKey); await circuitHost.DisposeAsync(); }
public override CircuitHost CreateCircuitHost( HttpContext httpContext, CircuitClientProxy client, string uriAbsolute, string baseUriAbsolute, ClaimsPrincipal user) { var components = ResolveComponentMetadata(httpContext, client); var scope = _scopeFactory.CreateScope(); var encoder = scope.ServiceProvider.GetRequiredService <HtmlEncoder>(); var jsRuntime = (RemoteJSRuntime)scope.ServiceProvider.GetRequiredService <IJSRuntime>(); var componentContext = (RemoteComponentContext)scope.ServiceProvider.GetRequiredService <IComponentContext>(); jsRuntime.Initialize(client); componentContext.Initialize(client); var uriHelper = (RemoteUriHelper)scope.ServiceProvider.GetRequiredService <IUriHelper>(); var navigationInterception = (RemoteNavigationInterception)scope.ServiceProvider.GetRequiredService <INavigationInterception>(); if (client.Connected) { uriHelper.AttachJsRuntime(jsRuntime); uriHelper.InitializeState( uriAbsolute, baseUriAbsolute); navigationInterception.AttachJSRuntime(jsRuntime); } else { uriHelper.InitializeState(uriAbsolute, baseUriAbsolute); } var rendererRegistry = new RendererRegistry(); var renderer = new RemoteRenderer( scope.ServiceProvider, _loggerFactory, rendererRegistry, jsRuntime, client, encoder, _loggerFactory.CreateLogger <RemoteRenderer>()); var circuitHandlers = scope.ServiceProvider.GetServices <CircuitHandler>() .OrderBy(h => h.Order) .ToArray(); var circuitHost = new CircuitHost( _circuitIdFactory.CreateCircuitId(), scope, client, rendererRegistry, renderer, components, jsRuntime, circuitHandlers, _loggerFactory.CreateLogger <CircuitHost>()); Log.CreatedCircuit(_logger, circuitHost); // Initialize per - circuit data that services need (circuitHost.Services.GetRequiredService <ICircuitAccessor>() as DefaultCircuitAccessor).Circuit = circuitHost.Circuit; circuitHost.SetCircuitUser(user); return(circuitHost); }
internal static void CreatedCircuit(ILogger logger, CircuitHost circuitHost) => _createdCircuit(logger, circuitHost.CircuitId.Id, circuitHost.Client.ConnectionId, null);
private static async Task CleanupCircuitState(HttpContext context, PrerenderingCancellationStatus cancellationStatus, CircuitHost circuitHost) { cancellationStatus.Canceled = true; context.Items.Remove(CircuitHostKey); await circuitHost.DisposeAsync(); }
internal Circuit(CircuitHost circuitHost) { JSRuntime = circuitHost.JSRuntime; Services = circuitHost.Services; }
public override CircuitHost CreateCircuitHost( HttpContext httpContext, CircuitClientProxy client, string uriAbsolute, string baseUriAbsolute) { var components = ResolveComponentMetadata(httpContext, client); var scope = _scopeFactory.CreateScope(); var encoder = scope.ServiceProvider.GetRequiredService <HtmlEncoder>(); var jsRuntime = (RemoteJSRuntime)scope.ServiceProvider.GetRequiredService <IJSRuntime>(); var componentContext = (RemoteComponentContext)scope.ServiceProvider.GetRequiredService <IComponentContext>(); jsRuntime.Initialize(client); componentContext.Initialize(client); // You can replace the AuthenticationStateProvider with a custom one, but in that case initialization is up to you var authenticationStateProvider = scope.ServiceProvider.GetService <AuthenticationStateProvider>(); (authenticationStateProvider as FixedAuthenticationStateProvider)?.Initialize(httpContext.User); var uriHelper = (RemoteUriHelper)scope.ServiceProvider.GetRequiredService <IUriHelper>(); if (client.Connected) { uriHelper.AttachJsRuntime(jsRuntime); uriHelper.InitializeState( uriAbsolute, baseUriAbsolute); } else { uriHelper.InitializeState(uriAbsolute, baseUriAbsolute); } var rendererRegistry = new RendererRegistry(); var dispatcher = Renderer.CreateDefaultDispatcher(); var renderer = new RemoteRenderer( scope.ServiceProvider, rendererRegistry, jsRuntime, client, dispatcher, encoder, _loggerFactory.CreateLogger <RemoteRenderer>()); var circuitHandlers = scope.ServiceProvider.GetServices <CircuitHandler>() .OrderBy(h => h.Order) .ToArray(); var circuitHost = new CircuitHost( scope, client, rendererRegistry, renderer, components, dispatcher, jsRuntime, circuitHandlers, _loggerFactory.CreateLogger <CircuitHost>()); // Initialize per - circuit data that services need (circuitHost.Services.GetRequiredService <ICircuitAccessor>() as DefaultCircuitAccessor).Circuit = circuitHost.Circuit; return(circuitHost); }
public override CircuitHost CreateCircuitHost( HttpContext httpContext, CircuitClientProxy client, string baseUri, string uri, ClaimsPrincipal user) { // We do as much intialization as possible eagerly in this method, which makes the error handling // story much simpler. If we throw from here, it's handled inside the initial hub method. var components = ResolveComponentMetadata(httpContext, client); var scope = _scopeFactory.CreateScope(); var encoder = scope.ServiceProvider.GetRequiredService <HtmlEncoder>(); var jsRuntime = (RemoteJSRuntime)scope.ServiceProvider.GetRequiredService <IJSRuntime>(); var componentContext = (RemoteComponentContext)scope.ServiceProvider.GetRequiredService <IComponentContext>(); jsRuntime.Initialize(client); componentContext.Initialize(client); var navigationManager = (RemoteNavigationManager)scope.ServiceProvider.GetRequiredService <NavigationManager>(); var navigationInterception = (RemoteNavigationInterception)scope.ServiceProvider.GetRequiredService <INavigationInterception>(); if (client.Connected) { navigationManager.AttachJsRuntime(jsRuntime); navigationManager.Initialize(baseUri, uri); navigationInterception.AttachJSRuntime(jsRuntime); } else { navigationManager.Initialize(baseUri, uri); } var renderer = new RemoteRenderer( scope.ServiceProvider, _loggerFactory, _options, jsRuntime, client, encoder, _loggerFactory.CreateLogger <RemoteRenderer>()); var circuitHandlers = scope.ServiceProvider.GetServices <CircuitHandler>() .OrderBy(h => h.Order) .ToArray(); var circuitHost = new CircuitHost( _circuitIdFactory.CreateCircuitId(), scope, client, renderer, components, jsRuntime, circuitHandlers, _loggerFactory.CreateLogger <CircuitHost>()); Log.CreatedCircuit(_logger, circuitHost); // Initialize per - circuit data that services need (circuitHost.Services.GetRequiredService <ICircuitAccessor>() as DefaultCircuitAccessor).Circuit = circuitHost.Circuit; circuitHost.SetCircuitUser(user); return(circuitHost); }
public void SetCircuit(IDictionary <object, object?> circuitHandles, object circuitKey, CircuitHost circuitHost) { circuitHandles[circuitKey] = circuitHost?.Handle; }