Updates to IComponentActivator PR
This commit is contained in:
parent
dae55edfec
commit
53588b45dc
|
|
@ -107,6 +107,11 @@ namespace Microsoft.AspNetCore.Components
|
||||||
protected virtual bool ShouldRender() { throw null; }
|
protected virtual bool ShouldRender() { throw null; }
|
||||||
protected void StateHasChanged() { }
|
protected void StateHasChanged() { }
|
||||||
}
|
}
|
||||||
|
public partial class DefaultComponentActivator : Microsoft.AspNetCore.Components.IComponentActivator
|
||||||
|
{
|
||||||
|
public DefaultComponentActivator() { }
|
||||||
|
public Microsoft.AspNetCore.Components.IComponent CreateInstance(System.Type componentType) { throw null; }
|
||||||
|
}
|
||||||
public abstract partial class Dispatcher
|
public abstract partial class Dispatcher
|
||||||
{
|
{
|
||||||
protected Dispatcher() { }
|
protected Dispatcher() { }
|
||||||
|
|
@ -234,6 +239,10 @@ namespace Microsoft.AspNetCore.Components
|
||||||
void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle);
|
void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle);
|
||||||
System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters);
|
System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters);
|
||||||
}
|
}
|
||||||
|
public partial interface IComponentActivator
|
||||||
|
{
|
||||||
|
Microsoft.AspNetCore.Components.IComponent CreateInstance(System.Type componentType);
|
||||||
|
}
|
||||||
public partial interface IHandleAfterRender
|
public partial interface IHandleAfterRender
|
||||||
{
|
{
|
||||||
System.Threading.Tasks.Task OnAfterRenderAsync();
|
System.Threading.Tasks.Task OnAfterRenderAsync();
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,9 @@ using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Components.Reflection;
|
using Microsoft.AspNetCore.Components.Reflection;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components
|
namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
/// <remarks>
|
|
||||||
/// The <see cref="Instance"/> property on this type is used as a static global cache. Ensure any changes to this type
|
|
||||||
/// are thread safe and can be safely cached statically.
|
|
||||||
/// </remarks>
|
|
||||||
internal class ComponentFactory
|
internal class ComponentFactory
|
||||||
{
|
{
|
||||||
private static readonly BindingFlags _injectablePropertyBindingFlags
|
private static readonly BindingFlags _injectablePropertyBindingFlags
|
||||||
|
|
@ -22,19 +17,20 @@ namespace Microsoft.AspNetCore.Components
|
||||||
private readonly ConcurrentDictionary<Type, Action<IServiceProvider, IComponent>> _cachedInitializers
|
private readonly ConcurrentDictionary<Type, Action<IServiceProvider, IComponent>> _cachedInitializers
|
||||||
= new ConcurrentDictionary<Type, Action<IServiceProvider, IComponent>>();
|
= new ConcurrentDictionary<Type, Action<IServiceProvider, IComponent>>();
|
||||||
|
|
||||||
public static readonly ComponentFactory Instance = new ComponentFactory();
|
private readonly IComponentActivator _componentActivator;
|
||||||
|
|
||||||
|
public ComponentFactory(IComponentActivator componentActivator)
|
||||||
|
{
|
||||||
|
_componentActivator = componentActivator ?? throw new ArgumentNullException(nameof(componentActivator));
|
||||||
|
}
|
||||||
|
|
||||||
public IComponent InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
|
public IComponent InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
|
||||||
{
|
{
|
||||||
var activator = serviceProvider.GetService<IComponentActivator>();
|
var component = _componentActivator.CreateInstance(componentType);
|
||||||
|
if (component is null)
|
||||||
var instance = activator != null
|
|
||||||
? activator.CreateInstance(componentType)
|
|
||||||
: Activator.CreateInstance(componentType);
|
|
||||||
|
|
||||||
if (!(instance is IComponent component))
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
|
// The default activator will never do this, but an externally-supplied one might
|
||||||
|
throw new InvalidOperationException($"The component activator returned a null value for a component of type {componentType.FullName}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformPropertyInjection(serviceProvider, component);
|
PerformPropertyInjection(serviceProvider, component);
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,25 @@ using System;
|
||||||
namespace Microsoft.AspNetCore.Components
|
namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default implementation of component activator.
|
/// Default implementation of <see cref="IComponentActivator"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DefaultComponentActivator : IComponentActivator
|
public class DefaultComponentActivator : IComponentActivator
|
||||||
{
|
{
|
||||||
|
// If no IComponentActivator is supplied by DI, the renderer uses this instance.
|
||||||
|
// It's internal because in the future, we might want to add per-scope state and then
|
||||||
|
// it would no longer be applicable to have a shared instance.
|
||||||
|
internal static IComponentActivator Instance { get; } = new DefaultComponentActivator();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IComponent? CreateInstance(Type componentType)
|
public IComponent CreateInstance(Type componentType)
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(componentType) as IComponent;
|
var instance = Activator.CreateInstance(componentType);
|
||||||
|
if (!(instance is IComponent component))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
return component;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,16 @@ namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an activator that can be used to instantiate components.
|
/// Represents an activator that can be used to instantiate components.
|
||||||
|
/// The activator is not responsible for dependency injection, since the framework
|
||||||
|
/// performs dependency injection to the resulting instances separately.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IComponentActivator
|
public interface IComponentActivator
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an component of the specified type using that type's default constructor.
|
/// Creates a component of the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="componentType">The type of component to create.</param>
|
/// <param name="componentType">The type of component to create.</param>
|
||||||
/// <returns>A reference to the newly created component.</returns>
|
/// <returns>A reference to the newly created component.</returns>
|
||||||
IComponent? CreateInstance(Type componentType);
|
IComponent CreateInstance(Type componentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Components.Profiling;
|
using Microsoft.AspNetCore.Components.Profiling;
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
using Microsoft.AspNetCore.Components.Rendering;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Components.RenderTree
|
namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
|
|
@ -29,6 +30,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
private readonly Dictionary<ulong, EventCallback> _eventBindings = new Dictionary<ulong, EventCallback>();
|
private readonly Dictionary<ulong, EventCallback> _eventBindings = new Dictionary<ulong, EventCallback>();
|
||||||
private readonly Dictionary<ulong, ulong> _eventHandlerIdReplacements = new Dictionary<ulong, ulong>();
|
private readonly Dictionary<ulong, ulong> _eventHandlerIdReplacements = new Dictionary<ulong, ulong>();
|
||||||
private readonly ILogger<Renderer> _logger;
|
private readonly ILogger<Renderer> _logger;
|
||||||
|
private readonly ComponentFactory _componentFactory;
|
||||||
|
|
||||||
private int _nextComponentId = 0; // TODO: change to 'long' when Mono .NET->JS interop supports it
|
private int _nextComponentId = 0; // TODO: change to 'long' when Mono .NET->JS interop supports it
|
||||||
private bool _isBatchInProgress;
|
private bool _isBatchInProgress;
|
||||||
|
|
@ -70,6 +72,10 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
|
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
_logger = loggerFactory.CreateLogger<Renderer>();
|
_logger = loggerFactory.CreateLogger<Renderer>();
|
||||||
|
|
||||||
|
var componentActivator = serviceProvider.GetService<IComponentActivator>()
|
||||||
|
?? DefaultComponentActivator.Instance;
|
||||||
|
_componentFactory = new ComponentFactory(componentActivator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -89,7 +95,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
|
||||||
/// <param name="componentType">The type of the component to instantiate.</param>
|
/// <param name="componentType">The type of the component to instantiate.</param>
|
||||||
/// <returns>The component instance.</returns>
|
/// <returns>The component instance.</returns>
|
||||||
protected IComponent InstantiateComponent(Type componentType)
|
protected IComponent InstantiateComponent(Type componentType)
|
||||||
=> ComponentFactory.Instance.InstantiateComponent(_serviceProvider, componentType);
|
=> _componentFactory.InstantiateComponent(_serviceProvider, componentType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Associates the <see cref="IComponent"/> with the <see cref="Renderer"/>, assigning
|
/// Associates the <see cref="IComponent"/> with the <see cref="Renderer"/>, assigning
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -17,7 +16,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var componentType = typeof(EmptyComponent);
|
var componentType = typeof(EmptyComponent);
|
||||||
var factory = new ComponentFactory();
|
var factory = new ComponentFactory(new DefaultComponentActivator());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
||||||
|
|
@ -28,44 +27,31 @@ namespace Microsoft.AspNetCore.Components
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InstantiateComponent_CreatesInstance_WithActivator()
|
public void InstantiateComponent_CreatesInstance_NonComponent()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var componentType = typeof(List<string>);
|
||||||
|
var factory = new ComponentFactory(new DefaultComponentActivator());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var ex = Assert.Throws<ArgumentException>(() => factory.InstantiateComponent(GetServiceProvider(), componentType));
|
||||||
|
Assert.StartsWith($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InstantiateComponent_CreatesInstance_WithCustomActivator()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var componentType = typeof(EmptyComponent);
|
var componentType = typeof(EmptyComponent);
|
||||||
var factory = new ComponentFactory();
|
var factory = new ComponentFactory(new CustomComponentActivator<ComponentWithInjectProperties>());
|
||||||
|
|
||||||
// Act
|
|
||||||
var instance = factory.InstantiateComponent(GetServiceProviderWithActivator(), componentType);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.NotNull(instance);
|
|
||||||
Assert.IsType<EmptyComponent>(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void InstantiateComponent_CreatesInstance_WithActivator_NonComponent()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var componentType = typeof(NonComponent);
|
|
||||||
var factory = new ComponentFactory();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Throws<ArgumentException>(()=>factory.InstantiateComponent(GetServiceProviderWithActivator(), componentType));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void InstantiateComponent_AssignsPropertiesWithInjectAttribute()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var componentType = typeof(ComponentWithInjectProperties);
|
|
||||||
var factory = new ComponentFactory();
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(instance);
|
Assert.NotNull(instance);
|
||||||
var component = Assert.IsType<ComponentWithInjectProperties>(instance);
|
var component = Assert.IsType<ComponentWithInjectProperties>(instance); // Custom activator returns a different type
|
||||||
|
|
||||||
// Public, and non-public properties, and properties with non-public setters should get assigned
|
// Public, and non-public properties, and properties with non-public setters should get assigned
|
||||||
Assert.NotNull(component.Property1);
|
Assert.NotNull(component.Property1);
|
||||||
Assert.NotNull(component.GetProperty2());
|
Assert.NotNull(component.GetProperty2());
|
||||||
|
|
@ -73,12 +59,24 @@ namespace Microsoft.AspNetCore.Components
|
||||||
Assert.NotNull(component.Property4);
|
Assert.NotNull(component.Property4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InstantiateComponent_ThrowsForNullInstance()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var componentType = typeof(EmptyComponent);
|
||||||
|
var factory = new ComponentFactory(new NullResultComponentActivator());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var ex = Assert.Throws<InvalidOperationException>(() => factory.InstantiateComponent(GetServiceProvider(), componentType));
|
||||||
|
Assert.Equal($"The component activator returned a null value for a component of type {componentType.FullName}.", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void InstantiateComponent_AssignsPropertiesWithInjectAttributeOnBaseType()
|
public void InstantiateComponent_AssignsPropertiesWithInjectAttributeOnBaseType()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var componentType = typeof(DerivedComponent);
|
var componentType = typeof(DerivedComponent);
|
||||||
var factory = new ComponentFactory();
|
var factory = new ComponentFactory(new CustomComponentActivator<DerivedComponent>());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
||||||
|
|
@ -101,7 +99,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var componentType = typeof(ComponentWithNonInjectableProperties);
|
var componentType = typeof(ComponentWithNonInjectableProperties);
|
||||||
var factory = new ComponentFactory();
|
var factory = new ComponentFactory(new DefaultComponentActivator());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
var instance = factory.InstantiateComponent(GetServiceProvider(), componentType);
|
||||||
|
|
@ -122,15 +120,6 @@ namespace Microsoft.AspNetCore.Components
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IServiceProvider GetServiceProviderWithActivator()
|
|
||||||
{
|
|
||||||
return new ServiceCollection()
|
|
||||||
.AddTransient<TestService1>()
|
|
||||||
.AddTransient<TestService2>()
|
|
||||||
.AddSingleton<IComponentActivator, DefaultComponentActivator>()
|
|
||||||
.BuildServiceProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class EmptyComponent : IComponent
|
private class EmptyComponent : IComponent
|
||||||
{
|
{
|
||||||
public void Attach(RenderHandle renderHandle)
|
public void Attach(RenderHandle renderHandle)
|
||||||
|
|
@ -197,9 +186,23 @@ namespace Microsoft.AspNetCore.Components
|
||||||
public TestService2 Property5 { get; set; }
|
public TestService2 Property5 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NonComponent { }
|
|
||||||
|
|
||||||
public class TestService1 { }
|
public class TestService1 { }
|
||||||
public class TestService2 { }
|
public class TestService2 { }
|
||||||
|
|
||||||
|
private class CustomComponentActivator<TResult> : IComponentActivator where TResult : IComponent, new()
|
||||||
|
{
|
||||||
|
public IComponent CreateInstance(Type componentType)
|
||||||
|
{
|
||||||
|
return new TResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NullResultComponentActivator : IComponentActivator
|
||||||
|
{
|
||||||
|
public IComponent CreateInstance(Type componentType)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Components.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
private T InstantiateComponent<T>() where T: IComponent
|
private T InstantiateComponent<T>() where T: IComponent
|
||||||
=> _renderer.InstantiateComponent<T>();
|
=> (T)_renderer.InstantiateComponent<T>();
|
||||||
|
|
||||||
class HasPropertiesWithoutInjectAttribute : TestComponent
|
class HasPropertiesWithoutInjectAttribute : TestComponent
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Components
|
||||||
|
|
||||||
var counter = serviceProvider.GetRequiredService<Counter>();
|
var counter = serviceProvider.GetRequiredService<Counter>();
|
||||||
var renderer = new TestRenderer(serviceProvider);
|
var renderer = new TestRenderer(serviceProvider);
|
||||||
var component1 = renderer.InstantiateComponent<MyOwningComponent>();
|
var component1 = (MyOwningComponent)renderer.InstantiateComponent<MyOwningComponent>();
|
||||||
|
|
||||||
Assert.NotNull(component1.MyService);
|
Assert.NotNull(component1.MyService);
|
||||||
Assert.Equal(1, counter.CreatedCount);
|
Assert.Equal(1, counter.CreatedCount);
|
||||||
|
|
|
||||||
|
|
@ -3733,6 +3733,35 @@ namespace Microsoft.AspNetCore.Components.Test
|
||||||
Assert.Equal($"The {nameof(ParameterView)} instance can no longer be read because it has expired. {nameof(ParameterView)} can only be read synchronously and must not be stored for later use.", ex.Message);
|
Assert.Equal($"The {nameof(ParameterView)} instance can no longer be read because it has expired. {nameof(ParameterView)} can only be read synchronously and must not be stored for later use.", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanUseCustomComponentActivator()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var serviceProvider = new TestServiceProvider();
|
||||||
|
var componentActivator = new TestComponentActivator<MessageComponent>();
|
||||||
|
serviceProvider.AddService<IComponentActivator>(componentActivator);
|
||||||
|
var renderer = new TestRenderer(serviceProvider);
|
||||||
|
|
||||||
|
// Act: Ask for TestComponent
|
||||||
|
var suppliedComponent = renderer.InstantiateComponent<TestComponent>();
|
||||||
|
|
||||||
|
// Assert: We actually receive MessageComponent
|
||||||
|
Assert.IsType<MessageComponent>(suppliedComponent);
|
||||||
|
Assert.Collection(componentActivator.RequestedComponentTypes,
|
||||||
|
requestedType => Assert.Equal(typeof(TestComponent), requestedType));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestComponentActivator<TResult> : IComponentActivator where TResult: IComponent, new()
|
||||||
|
{
|
||||||
|
public List<Type> RequestedComponentTypes { get; } = new List<Type>();
|
||||||
|
|
||||||
|
public IComponent CreateInstance(Type componentType)
|
||||||
|
{
|
||||||
|
RequestedComponentTypes.Add(componentType);
|
||||||
|
return new TResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class NoOpRenderer : Renderer
|
private class NoOpRenderer : Renderer
|
||||||
{
|
{
|
||||||
public NoOpRenderer() : base(new TestServiceProvider(), NullLoggerFactory.Instance)
|
public NoOpRenderer() : base(new TestServiceProvider(), NullLoggerFactory.Instance)
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
services.AddScoped<IJSRuntime, RemoteJSRuntime>();
|
services.AddScoped<IJSRuntime, RemoteJSRuntime>();
|
||||||
services.AddScoped<INavigationInterception, RemoteNavigationInterception>();
|
services.AddScoped<INavigationInterception, RemoteNavigationInterception>();
|
||||||
services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
|
services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
|
||||||
services.AddScoped<IComponentActivator, DefaultComponentActivator>();
|
|
||||||
|
|
||||||
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJSInteropDetailedErrorsConfiguration>());
|
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJSInteropDetailedErrorsConfiguration>());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,8 @@ namespace Microsoft.AspNetCore.Components.Test.Helpers
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T InstantiateComponent<T>() where T : IComponent
|
public IComponent InstantiateComponent<T>()
|
||||||
=> (T)InstantiateComponent(typeof(T));
|
=> InstantiateComponent(typeof(T));
|
||||||
|
|
||||||
protected override void HandleException(Exception exception)
|
protected override void HandleException(Exception exception)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -212,13 +212,12 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
services.TryAddScoped<NavigationManager, HttpNavigationManager>();
|
services.TryAddScoped<NavigationManager, HttpNavigationManager>();
|
||||||
services.TryAddScoped<IJSRuntime, UnsupportedJavaScriptRuntime>();
|
services.TryAddScoped<IJSRuntime, UnsupportedJavaScriptRuntime>();
|
||||||
services.TryAddScoped<INavigationInterception, UnsupportedNavigationInterception>();
|
services.TryAddScoped<INavigationInterception, UnsupportedNavigationInterception>();
|
||||||
|
|
||||||
services.TryAddTransient<ControllerSaveTempDataPropertyFilter>();
|
services.TryAddTransient<ControllerSaveTempDataPropertyFilter>();
|
||||||
|
|
||||||
// This does caching so it should stay singleton
|
// This does caching so it should stay singleton
|
||||||
services.TryAddSingleton<ITempDataProvider, CookieTempDataProvider>();
|
services.TryAddSingleton<ITempDataProvider, CookieTempDataProvider>();
|
||||||
services.TryAddSingleton<TempDataSerializer, DefaultTempDataSerializer>();
|
services.TryAddSingleton<TempDataSerializer, DefaultTempDataSerializer>();
|
||||||
services.TryAddSingleton<IComponentActivator, DefaultComponentActivator>();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Antiforgery
|
// Antiforgery
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue