CR: Add ctor overload accepting IComponentActivator

This commit is contained in:
Steve Sanderson 2020-07-07 11:47:19 +01:00
parent 9e365f4356
commit 0ec15ea01d
4 changed files with 48 additions and 4 deletions

View File

@ -477,6 +477,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree
public abstract partial class Renderer : System.IDisposable public abstract partial class Renderer : System.IDisposable
{ {
public Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
public Renderer(System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.Components.IComponentActivator componentActivator) { }
public abstract Microsoft.AspNetCore.Components.Dispatcher Dispatcher { get; } public abstract Microsoft.AspNetCore.Components.Dispatcher Dispatcher { get; }
protected internal Microsoft.AspNetCore.Components.ElementReferenceContext? ElementReferenceContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } protected internal Microsoft.AspNetCore.Components.ElementReferenceContext? ElementReferenceContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
public event System.UnhandledExceptionEventHandler UnhandledSynchronizationException { add { } remove { } } public event System.UnhandledExceptionEventHandler UnhandledSynchronizationException { add { } remove { } }

View File

@ -59,6 +59,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree
/// <param name="serviceProvider">The <see cref="IServiceProvider"/> to be used when initializing components.</param> /// <param name="serviceProvider">The <see cref="IServiceProvider"/> to be used when initializing components.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param> /// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
public Renderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory) public Renderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory)
: this(serviceProvider, loggerFactory, GetComponentActivatorOrDefault(serviceProvider))
{
// This overload is provided for back-compatibility
}
/// <summary>
/// Constructs an instance of <see cref="Renderer"/>.
/// </summary>
/// <param name="serviceProvider">The <see cref="IServiceProvider"/> to be used when initializing components.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
/// <param name="componentActivator">The <see cref="IComponentActivator"/>.</param>
public Renderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, IComponentActivator componentActivator)
{ {
if (serviceProvider is null) if (serviceProvider is null)
{ {
@ -70,14 +82,22 @@ namespace Microsoft.AspNetCore.Components.RenderTree
throw new ArgumentNullException(nameof(loggerFactory)); throw new ArgumentNullException(nameof(loggerFactory));
} }
if (componentActivator is null)
{
throw new ArgumentNullException(nameof(componentActivator));
}
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_logger = loggerFactory.CreateLogger<Renderer>(); _logger = loggerFactory.CreateLogger<Renderer>();
var componentActivator = serviceProvider.GetService<IComponentActivator>()
?? DefaultComponentActivator.Instance;
_componentFactory = new ComponentFactory(componentActivator); _componentFactory = new ComponentFactory(componentActivator);
} }
private static IComponentActivator GetComponentActivatorOrDefault(IServiceProvider serviceProvider)
{
return serviceProvider.GetService<IComponentActivator>()
?? DefaultComponentActivator.Instance;
}
/// <summary> /// <summary>
/// Gets the <see cref="Microsoft.AspNetCore.Components.Dispatcher" /> associated with this <see cref="Renderer" />. /// Gets the <see cref="Microsoft.AspNetCore.Components.Dispatcher" /> associated with this <see cref="Renderer" />.
/// </summary> /// </summary>

View File

@ -3734,7 +3734,24 @@ namespace Microsoft.AspNetCore.Components.Test
} }
[Fact] [Fact]
public void CanUseCustomComponentActivator() public void CanUseCustomComponentActivatorFromConstructorParameter()
{
// Arrange
var serviceProvider = new TestServiceProvider();
var componentActivator = new TestComponentActivator<MessageComponent>();
var renderer = new TestRenderer(serviceProvider, componentActivator);
// 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));
}
[Fact]
public void CanUseCustomComponentActivatorFromServiceProvider()
{ {
// Arrange // Arrange
var serviceProvider = new TestServiceProvider(); var serviceProvider = new TestServiceProvider();

View File

@ -29,6 +29,12 @@ namespace Microsoft.AspNetCore.Components.Test.Helpers
Dispatcher = Dispatcher.CreateDefault(); Dispatcher = Dispatcher.CreateDefault();
} }
public TestRenderer(IServiceProvider serviceProvider, IComponentActivator componentActivator)
: base(serviceProvider, NullLoggerFactory.Instance, componentActivator)
{
Dispatcher = Dispatcher.CreateDefault();
}
public override Dispatcher Dispatcher { get; } public override Dispatcher Dispatcher { get; }
public Action OnExceptionHandled { get; set; } public Action OnExceptionHandled { get; set; }