Skip to content

Commit dd25f77

Browse files
authored
feat: Enable constructor injection (#1581)
* feat: Enable constructor injection * fix: CVE in System.Text.Json
1 parent 8ff1bf3 commit dd25f77

File tree

5 files changed

+45
-14
lines changed

5 files changed

+45
-14
lines changed

Directory.Packages.props

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<GlobalPackageReference Include="AsyncFixer" Version="1.6.0" PrivateAssets="All" IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"/>
99
<GlobalPackageReference Include="SonarAnalyzer.CSharp" Version="9.32.0.97167" PrivateAssets="All" IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"/>
1010
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
11-
<PackageVersion Include="Meziantou.Polyfill" Version="1.0.39" />
11+
<PackageVersion Include="Meziantou.Polyfill" Version="1.0.40" />
1212
</ItemGroup>
1313

1414
<ItemGroup Label="Shared">
@@ -42,7 +42,7 @@
4242
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="3.2.1"/>
4343

4444
<!-- Due to a CVE in System.Text.Json we explicitly reference the latest version of System.Text.Json -->
45-
<PackageVersion Include="System.Text.Json" Version="6.0.9"/>
45+
<PackageVersion Include="System.Text.Json" Version="6.0.10"/>
4646
</ItemGroup>
4747

4848
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
@@ -59,7 +59,7 @@
5959
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="5.0.17"/>
6060

6161
<!-- Due to a CVE in System.Text.Json we explicitly reference the latest version of System.Text.Json -->
62-
<PackageVersion Include="System.Text.Json" Version="6.0.9"/>
62+
<PackageVersion Include="System.Text.Json" Version="6.0.10"/>
6363
</ItemGroup>
6464

6565
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
@@ -75,7 +75,7 @@
7575
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.33"/>
7676

7777
<!-- Due to a CVE in System.Text.Json we explicitly reference the latest version of System.Text.Json -->
78-
<PackageVersion Include="System.Text.Json" Version="6.0.9"/>
78+
<PackageVersion Include="System.Text.Json" Version="6.0.10"/>
7979
</ItemGroup>
8080

8181
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
@@ -91,7 +91,7 @@
9191
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.20"/>
9292

9393
<!-- Due to a CVE in System.Text.Json we explicitly reference the latest version of System.Text.Json -->
94-
<PackageVersion Include="System.Text.Json" Version="8.0.4"/>
94+
<PackageVersion Include="System.Text.Json" Version="8.0.5"/>
9595
</ItemGroup>
9696

9797
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
@@ -107,7 +107,7 @@
107107
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.8"/>
108108

109109
<!-- Due to a CVE in System.Text.Json we explicitly reference the latest version of System.Text.Json -->
110-
<PackageVersion Include="System.Text.Json" Version="8.0.4"/>
110+
<PackageVersion Include="System.Text.Json" Version="8.0.5"/>
111111
</ItemGroup>
112112

113113
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
@@ -122,7 +122,7 @@
122122
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0-rc.1.24452.1"/>
123123
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.0-rc.1.24452.1"/>
124124

125-
<PackageVersion Include="System.Text.Json" Version="8.0.4" />
125+
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
126126
</ItemGroup>
127127

128128
<ItemGroup Label="Test Dependencies">

src/bunit.core/Rendering/BunitComponentActivator.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ internal class BunitComponentActivator : IComponentActivator
77
private readonly ComponentFactoryCollection factories;
88
private readonly IComponentActivator componentActivator;
99

10-
public BunitComponentActivator(ComponentFactoryCollection factories, IComponentActivator? externalComponentActivator)
10+
public BunitComponentActivator(
11+
IServiceProvider serviceProvider,
12+
ComponentFactoryCollection factories,
13+
IComponentActivator? externalComponentActivator)
1114
{
1215
this.factories = factories ?? throw new ArgumentNullException(nameof(factories));
13-
this.componentActivator = externalComponentActivator ?? DefaultComponentActivator.Instance;
16+
this.componentActivator = externalComponentActivator ?? new DefaultComponentActivator(serviceProvider);
1417
}
1518

1619
public IComponent CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type componentType)
@@ -43,12 +46,17 @@ public IComponent CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessed
4346

4447
private sealed class DefaultComponentActivator : IComponentActivator
4548
{
46-
public static IComponentActivator Instance { get; } = new DefaultComponentActivator();
49+
private readonly IServiceProvider serviceProvider;
50+
51+
public DefaultComponentActivator(IServiceProvider serviceProvider)
52+
{
53+
this.serviceProvider = serviceProvider;
54+
}
4755

4856
/// <inheritdoc />
4957
public IComponent CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type componentType)
50-
{
51-
return (IComponent)Activator.CreateInstance(componentType)!;
58+
{
59+
return (IComponent)ActivatorUtilities.CreateInstance(serviceProvider, componentType);
5260
}
5361
}
5462
}

src/bunit.core/Rendering/TestRenderer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public TestRenderer(IRenderedComponentActivator renderedComponentActivator, Test
7979
/// Initializes a new instance of the <see cref="TestRenderer"/> class.
8080
/// </summary>
8181
public TestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory)
82-
: base(services, loggerFactory, new BunitComponentActivator(services.GetRequiredService<ComponentFactoryCollection>(), null))
82+
: base(services, loggerFactory, new BunitComponentActivator(services, services.GetRequiredService<ComponentFactoryCollection>(), null))
8383
{
8484
logger = loggerFactory.CreateLogger<TestRenderer>();
8585
this.activator = renderedComponentActivator;
@@ -89,7 +89,7 @@ public TestRenderer(IRenderedComponentActivator renderedComponentActivator, Test
8989
/// Initializes a new instance of the <see cref="TestRenderer"/> class.
9090
/// </summary>
9191
public TestRenderer(IRenderedComponentActivator renderedComponentActivator, TestServiceProvider services, ILoggerFactory loggerFactory, IComponentActivator componentActivator)
92-
: base(services, loggerFactory, new BunitComponentActivator(services.GetRequiredService<ComponentFactoryCollection>(), componentActivator))
92+
: base(services, loggerFactory, new BunitComponentActivator(services, services.GetRequiredService<ComponentFactoryCollection>(), componentActivator))
9393
{
9494
logger = loggerFactory.CreateLogger<TestRenderer>();
9595
this.activator = renderedComponentActivator;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Microsoft.JSInterop;
2+
3+
namespace Bunit.TestAssets.SampleComponents;
4+
5+
public class ConstructorInjectionComponent : ComponentBase
6+
{
7+
public IJSRuntime JSRuntime { get; }
8+
9+
public ConstructorInjectionComponent(IJSRuntime jsRuntime)
10+
{
11+
JSRuntime = jsRuntime;
12+
}
13+
}

tests/bunit.web.tests/Rendering/RenderedComponentTest.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,14 @@ public void Test020()
5757

5858
Should.Throw<ComponentDisposedException>(() => target.Instance);
5959
}
60+
#if NET9_0_OR_GREATER
61+
62+
[Fact(DisplayName = "Component with constructor dependencies is resolved when rendered")]
63+
public void Test021()
64+
{
65+
var cut = RenderComponent<ConstructorInjectionComponent>();
66+
67+
cut.Instance.JSRuntime.ShouldNotBeNull();
68+
}
69+
#endif
6070
}

0 commit comments

Comments
 (0)