Add IComponentActivator
This commit is contained in:
parent
156023d3f9
commit
dae55edfec
|
|
@ -6,6 +6,7 @@ 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
|
||||||
{
|
{
|
||||||
|
|
@ -25,7 +26,12 @@ namespace Microsoft.AspNetCore.Components
|
||||||
|
|
||||||
public IComponent InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
|
public IComponent InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
|
||||||
{
|
{
|
||||||
var instance = Activator.CreateInstance(componentType);
|
var activator = serviceProvider.GetService<IComponentActivator>();
|
||||||
|
|
||||||
|
var instance = activator != null
|
||||||
|
? activator.CreateInstance(componentType)
|
||||||
|
: Activator.CreateInstance(componentType);
|
||||||
|
|
||||||
if (!(instance is IComponent component))
|
if (!(instance is IComponent component))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
|
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default implementation of component activator.
|
||||||
|
/// </summary>
|
||||||
|
public class DefaultComponentActivator : IComponentActivator
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IComponent? CreateInstance(Type componentType)
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance(componentType) as IComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an activator that can be used to instantiate components.
|
||||||
|
/// </summary>
|
||||||
|
public interface IComponentActivator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an component of the specified type using that type's default constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="componentType">The type of component to create.</param>
|
||||||
|
/// <returns>A reference to the newly created component.</returns>
|
||||||
|
IComponent? CreateInstance(Type componentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,32 @@ namespace Microsoft.AspNetCore.Components
|
||||||
Assert.IsType<EmptyComponent>(instance);
|
Assert.IsType<EmptyComponent>(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InstantiateComponent_CreatesInstance_WithActivator()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var componentType = typeof(EmptyComponent);
|
||||||
|
var factory = new ComponentFactory();
|
||||||
|
|
||||||
|
// 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]
|
[Fact]
|
||||||
public void InstantiateComponent_AssignsPropertiesWithInjectAttribute()
|
public void InstantiateComponent_AssignsPropertiesWithInjectAttribute()
|
||||||
{
|
{
|
||||||
|
|
@ -96,6 +122,15 @@ 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)
|
||||||
|
|
@ -162,6 +197,8 @@ 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 { }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ 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>());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
// 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