如何构建模块化Blazor Web应用?ExtCore API场景下的适配问询
Hey Jon, let's work through this modular Blazor + ExtCore setup challenge you're hitting. The core issue here is that traditional Blazor WebAssembly projects used to target .NET Standard, but ExtCore relies on .NET Core/.NET 5+ runtime features. Luckily, newer .NET versions fix this compatibility gap, and we can structure your modular setup properly without crashes. Here's a step-by-step breakdown:
Forget trying to force a .NET Standard Blazor project to be .NET Core directly—starting with .NET 6+, Blazor WebAssembly supports targeting .NET 6/7/8 natively (no more .NET Standard required). This aligns with ExtCore's requirements while keeping Blazor's WASM runtime happy.
Update your Blazor project's .csproj to target a modern .NET version, and ensure the Blazor SDK is set correctly:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <BlazorWebAssembly>true</BlazorWebAssembly> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <!-- Add ExtCore core packages here --> <ItemGroup> <PackageReference Include="ExtCore" Version="7.1.0" /> <PackageReference Include="ExtCore.Infrastructure" Version="7.1.0" /> </ItemGroup> </Project>
Do the same for each of your modular Blazor component projects—set their target framework to match the core project (e.g., net8.0).
ExtCore's modular system works by loading assemblies and executing module initialization code. Here's how to turn your Blazor components into valid ExtCore modules:
- For each component module project:
- Implement the
IModuleinterface fromExtCore.Infrastructure. - In the
Initializemethod, register any services your components need (like data services, custom handlers) with the DI container. - Keep your
.razorcomponents (note: Blazor uses.razorinstead of.cshtmlfor components/pages, though.cshtmlstill works for Razor Pages) public in the module project.
- Implement the
Example module implementation:
using ExtCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; namespace MyBlazorModule; public class Module : IModule { public void Initialize(IServiceCollection services) { // Register module-specific services here services.AddScoped<IMyModuleService, MyModuleService>(); } public void Configure(IApplicationBuilder app) { // Optional: Configure middleware for the module if needed } }
You don't need to manually import .razor/.cshtml files into your core project. ExtCore loads the module assemblies, and Blazor's runtime will automatically discover:
- Page components: Any component with a
@pagedirective will be added to Blazor's routing system automatically. - Shared components: Public components in module assemblies can be referenced in your core project or other modules by their full namespace (e.g.,
<MyBlazorModule.MySharedComponent />).
If you need dynamic component loading (like rendering components based on module availability), use Blazor's <DynamicComponent>:
@using System.Reflection @inject IServiceProvider ServiceProvider @foreach (var module in ExtCore.Infrastructure.Extensions.Modules.AvailableModules) { // Find components marked with a custom attribute, or by namespace var componentTypes = module.Assembly.GetTypes() .Where(t => t.IsSubclassOf(typeof(ComponentBase)) && t.IsPublic); foreach (var type in componentTypes) { <DynamicComponent Type="@type" /> } }
If your modules have CSS, JS, or image files, place them in the module's wwwroot folder. Then, in your core project's Program.cs, add code to serve these static assets from loaded modules:
var app = builder.Build(); // Serve core project static files first app.UseStaticFiles(); // Serve static files from each ExtCore module foreach (var module in ExtCore.Infrastructure.Extensions.Modules.AvailableModules) { var moduleWwwrootPath = Path.Combine(AppContext.BaseDirectory, module.Assembly.FullName, "wwwroot"); if (Directory.Exists(moduleWwwrootPath)) { app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(moduleWwwrootPath), RequestPath = $"/modules/{module.Name}" }); } } // Rest of your app setup (routing, etc.) app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Run();
If you still run into crashes after these changes:
- Double-check that all module projects are targeting the same .NET version as the core project.
- Remove any old .NET Standard packages from your dependencies—upgrade them to their .NET 6+ equivalents.
- Check the browser's developer console for detailed error messages (Blazor WASM crashes almost always leave clear clues there, like missing assemblies or incompatible dependencies).
This setup should let you leverage ExtCore's modular architecture for both your API and Blazor SPA, keeping everything decoupled and maintainable.
内容的提问来源于stack exchange,提问作者Jon Ryan

