Skip to content

Commit 4fa54fa

Browse files
committed
[Design] Add service provider factory support
Fixes: #18814 This is an attempt to add back support on the Blazor WASM Host for using ISerivceProviderFactory<>. We previously had this support when the Blazor WASM host was a clone of generic host, but I accidentally lost it when simplifying the host (sorry :( ).
1 parent f5f51f5 commit 4fa54fa

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostBuilder.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ namespace Microsoft.AspNetCore.Blazor.Hosting
2121
/// </summary>
2222
public sealed class WebAssemblyHostBuilder
2323
{
24+
private Func<IServiceProvider> _createServiceProvider;
25+
2426
/// <summary>
2527
/// Creates an instance of <see cref="WebAssemblyHostBuilder"/> using the most common
2628
/// conventions and settings.
@@ -54,6 +56,11 @@ private WebAssemblyHostBuilder()
5456
Services = new ServiceCollection();
5557

5658
InitializeDefaultServices();
59+
60+
_createServiceProvider = () =>
61+
{
62+
return Services.BuildServiceProvider();
63+
};
5764
}
5865

5966
/// <summary>
@@ -72,6 +79,45 @@ private WebAssemblyHostBuilder()
7279
/// </summary>
7380
public IServiceCollection Services { get; }
7481

82+
/// <summary>
83+
/// Registers a <see cref="IServiceProviderFactory{TBuilder}" /> instance to be used to create the <see cref="IServiceProvider" />.
84+
/// </summary>
85+
/// <param name="factory">The <see cref="IServiceProviderFactory{TBuilder}" />.</param>
86+
/// <typeparam name="TBuilder">The type of builder provided by the <see cref="IServiceProviderFactory{TBuilder}" />.</typeparam>
87+
public void ConfigureContainer<TBuilder>(IServiceProviderFactory<TBuilder> factory)
88+
{
89+
if (factory == null)
90+
{
91+
throw new ArgumentNullException(nameof(factory));
92+
}
93+
94+
ConfigureContainer(factory, configure: null);
95+
}
96+
97+
/// <summary>
98+
/// Registers a <see cref="IServiceProviderFactory{TBuilder}" /> instance to be used to create the <see cref="IServiceProvider" />.
99+
/// </summary>
100+
/// <param name="factory">The <see cref="IServiceProviderFactory{TBuilder}" />.</param>
101+
/// <param name="configure">
102+
/// A delegate used to configure the <typeparamref T="TBuilder" />. This can be used to configure services using
103+
/// APIS specific to the <see cref="IServiceProviderFactory{TBuilder}" /> implementation.
104+
/// </param>
105+
/// <typeparam name="TBuilder">The type of builder provided by the <see cref="IServiceProviderFactory{TBuilder}" />.</typeparam>
106+
public void ConfigureContainer<TBuilder>(IServiceProviderFactory<TBuilder> factory, Action<TBuilder> configure)
107+
{
108+
if (factory == null)
109+
{
110+
throw new ArgumentNullException(nameof(factory));
111+
}
112+
113+
_createServiceProvider = () =>
114+
{
115+
var container = factory.CreateBuilder(Services);
116+
configure?.Invoke(container);
117+
return factory.CreateServiceProvider(container);
118+
};
119+
}
120+
75121
/// <summary>
76122
/// Builds a <see cref="WebAssemblyHost"/> instance based on the configuration of this builder.
77123
/// </summary>
@@ -85,7 +131,7 @@ public WebAssemblyHost Build()
85131
// A Blazor application always runs in a scope. Since we want to make it possible for the user
86132
// to configure services inside *that scope* inside their startup code, we create *both* the
87133
// service provider and the scope here.
88-
var services = Services.BuildServiceProvider();
134+
var services = _createServiceProvider();
89135
var scope = services.GetRequiredService<IServiceScopeFactory>().CreateScope();
90136

91137
return new WebAssemblyHost(services, scope, configuration, RootComponents.ToArray());

0 commit comments

Comments
 (0)