Step-by-step instructions for creating a brand new module in the AppProject .NET template. Covers creating all backend and frontend projects, registering assemblies in bootstrap files, configuring lazy loading, and adding menu items. Use when the user needs to create a completely new module (not just a new entity in an existing module).
Follow these steps when you need to create an entirely new module (not just a new entity in an existing module like General). Use the General module as the reference.
Create the following projects (replace <NewModule> with the module name):
src/AppProject.Core.Models.<NewModule>/AppProject.Core.Models.<NewModule>.csproj
Reference: AppProject.Core.Models.General.csproj
src/AppProject.Core.Services.<NewModule>/AppProject.Core.Services.<NewModule>.csproj
Reference:
AppProject.Core.Services.General.csprojsrc/AppProject.Core.Controllers.<NewModule>/AppProject.Core.Controllers.<NewModule>.csproj
Reference: AppProject.Core.Controllers.General.csproj
Create inside src/AppProject.Core.Infrastructure.Database/:
Entities/<NewModule>/EntityTypeConfiguration/<NewModule>/Mapper/<NewModule>/ (only if custom Mapster configs needed)src/AppProject.Core.Services/<NewModule>/
For summary services shared across modules.
src/AppProject.Core.Models/<NewModule>/
For summary DTOs and search requests shared across modules.
src/AppProject.Web.<NewModule>/AppProject.Web.<NewModule>.csproj
Reference: AppProject.Web.General.csproj
src/AppProject.Web.ApiClient.<NewModule>/AppProject.Web.ApiClient.<NewModule>.csproj
Reference: AppProject.Web.ApiClient.General.csproj
src/AppProject.Web.Models.<NewModule>/AppProject.Web.Models.<NewModule>.csproj
Reference: AppProject.Web.Models.General.csproj
src/AppProject.Web.ApiClient/<NewModule>/ — shared Refit summary clientssrc/AppProject.Web.Models/<NewModule>/ — shared observable summary modelssrc/AppProject.Web.Shared/<NewModule>/Components/ — shared dropdown/card componentssrc/AppProject.Core.Tests.<NewModule>/AppProject.Core.Tests.<NewModule>.csproj
Reference: AppProject.Core.Tests.General.csproj
src/AppProject.Web.Tests.<NewModule>/AppProject.Web.Tests.<NewModule>.csproj
File: src/AppProject.Core.API/Bootstraps/Bootstrap.cs
Add the controller assembly to GetControllerAssemblies():
Assembly.Load("AppProject.Core.Controllers.<NewModule>"),
Add the service assembly to GetServiceAssemblies():
Assembly.Load("AppProject.Core.Services.<NewModule>"),
Note: The shared service assembly AppProject.Core.Services is already registered, so summary services placed there are auto-discovered.
File: src/AppProject.Web/Bootstraps/WebBootstrap.cs
Add to GetApiClientAssemblies():
Assembly.Load("AppProject.Web.ApiClient.<NewModule>"),
Note: The shared AppProject.Web.ApiClient assembly is already registered.
File: src/AppProject.Web/App.razor
In OnNavigateAsync, add assembly loading for the new module's route prefix:
if (args.Path.StartsWith("<newmodule_lowercase>"))
{
var assemblies = new List<Assembly> { typeof(AppProject.Web.<NewModule>.Pages.<SomePage>).Assembly };
additionalAssemblies.AddRange(assemblies);
}
File: src/AppProject.Web/AppProject.Web.csproj
Add project references:
<ProjectReference Include="..\AppProject.Web.<NewModule>\AppProject.Web.<NewModule>.csproj" />
<ProjectReference Include="..\AppProject.Web.ApiClient.<NewModule>\AppProject.Web.ApiClient.<NewModule>.csproj" />
<ProjectReference Include="..\AppProject.Web.Models.<NewModule>\AppProject.Web.Models.<NewModule>.csproj" />
Add lazy load entry:
<BlazorWebAssemblyLazyLoad Include="AppProject.Web.<NewModule>.dll" />
File: src/AppProject.Web/Layout/NavMenu.razor
Add navigation items for the new module with the appropriate permission check:
@if (hasPermission_<NewModule>)
{
<RadzenPanelMenuItem [email protected]("NavMenu_<NewModule>_Title") Icon="category">
<RadzenPanelMenuItem [email protected]("NavMenu_<NewModule>_<EntityName>_Text")
Path="<newmodule_lowercase>/<plural_entity_lowercase>" Icon="list" />
</RadzenPanelMenuItem>
}
Add translation keys to all three .resx files for:
NavMenu_<NewModule>_Title, NavMenu_<NewModule>_<EntityName>_TextAdd all new projects to the solution file:
cd src
dotnet sln AppProject.slnx add AppProject.Core.Models.<NewModule>/AppProject.Core.Models.<NewModule>.csproj
dotnet sln AppProject.slnx add AppProject.Core.Services.<NewModule>/AppProject.Core.Services.<NewModule>.csproj
dotnet sln AppProject.slnx add AppProject.Core.Controllers.<NewModule>/AppProject.Core.Controllers.<NewModule>.csproj
dotnet sln AppProject.slnx add AppProject.Web.<NewModule>/AppProject.Web.<NewModule>.csproj
dotnet sln AppProject.slnx add AppProject.Web.ApiClient.<NewModule>/AppProject.Web.ApiClient.<NewModule>.csproj
dotnet sln AppProject.slnx add AppProject.Web.Models.<NewModule>/AppProject.Web.Models.<NewModule>.csproj
dotnet sln AppProject.slnx add AppProject.Core.Tests.<NewModule>/AppProject.Core.Tests.<NewModule>.csproj
ProjectReference, verify if the dependency is already accessible via shared assemblies (e.g., AppProject.Core.Services already references Jobs, so new modules don't need to reference Jobs directly).api/<newmodule_lowercase>/[controller]/[action]./<newmodule_lowercase>/<plural_entity_lowercase>..resx files