ModuWeb is a .NET web application that supports dynamic runtime loading, reloading, and unloading of external modules (.dll files).
Each module is self-contained and can expose custom HTTP routes, CORS policies, and request handlers.
- 🔄 Hot-reloadable modules – automatically reloads modules when their
.dllfiles are updated or replaced. - 📁 File system watching – monitors the
modules/folder for.dllchanges usingFileSystemWatcher. - 🌐 Per-module CORS – modules define their own CORS rules.
- 🔀 Custom middleware routing – routes HTTP requests to appropriate modules based on URL.
- 💾 Session support – every module can create and/or use session storage.
- ⚡ Event system – allows modules to subscribe to and react to system events.
- 💬 Message system – enables modules to communicate with each other.
- 🧾 Built-in logger – simple color-coded console logger for info, warnings, and errors.
ModuWeb/
│
├── Properties/
│ └── launchSettings.json # Startup settings for dev mode
│
├── Events/
│ ├── Events.cs # Contains all events
│ ├── ModuleLoadedEventArgs.cs # Args for event about loaded module
│ ├── ModuleMessageSentEventArgs.cs # Args for event about sent message
│ ├── ModuleUnloadedEventArgs.cs # Args for event about unloaded module
│ ├── RequestRecievedEventArgs.cs # Args for event about recieved http request
│ └── SafeEvent.cs # Base and safe class for events
│
├── examples/ # Examples modules
│
├── Extensions/
│ ├── ArrayExtention.cs # Little extention for array
│ ├── HttpRequestExtention.cs # Extention for get request data (from query string or json body)
│ └── StringExtention.cs # Little extention for string.Replace(old, new, count)
│
├── ModuleLoadSystem/
│ ├── ModuleLoadContext.cs # Custom AssemblyLoadContext
│ ├── ModuleManager.cs # Loads/unloads modules and handles lifecycle
│ └── ModuleWatcher.cs # Watches for module file changes
│
├── ModuleMessenger/
│ ├── ModuleMessage.cs # Module message that every moudle can create and receive
│ └── ModuleMessenger.cs # System handler for module messages
│
├── SessionSystem/
│ ├── ISessionService.cs # Interface of session service
│ ├── LiteDbSessionService.cs # Session service for create and working with sessions
│ └── SessionData.cs # Data that store into database
│
├── Storage/
│ ├── IStorageService.cs # Interface of storage service
│ └── LiteDbStorageService.cs # Data that store into database
│
├── appsettings.json # Default appsettings
├── DynamicCorsPolicyProvider.cs # CORS policy provider per module
├── LICENSE.txt # License for this project
├── Logger.cs # Static logger with color output
├── ModuleBase.cs # Base class for all modules
├── ModuleCorsGuardMiddleware # Middleware for handling CORS per module
├── Program.cs # Application entry point
├── QueryParser.cs # Tool for parse args from query
└── RouteDictionary.cs # Path + method → handler registry
To run the project, make sure you have the .NET Runtime (Microsoft.AspNetCore.App) or SDK version 9.0.2 or higher installed.
dotnet --list-sdksIf it's installed, you must see something like that:
9.0.200 [C:\Program Files\dotnet\sdk]
If it's not installed, you need to install it there.
dotnet --list-runtimesIf it's installed, you must see something like that:
Microsoft.AspNetCore.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
If it's not installed, you need to install it there. Choose Run server apps.
- Clone the repository:
git clone https://github.com/Chaleshka/ModuWeb.git
cd ModuWeb- Build the solution using .NET SDK 9.0.2+.
dotnet build- Run the app:
dotnet run- Download the latest release from the Releases page
- Extract the archive to your preferred directory
- Launch the app:
# Windows
ModuWeb.exe
# Linux/macOS:
dotnet ModuWeb.dllAfter launching the program, the modules folder will be created. You need to put all the modules you need in it.
Also, if dependencies are required, drop them in the modules/dependencies folder.
If everything is fine with the modules, they will be loaded automatically.
Firstly create project:
dotnet new classlib -n ModuleName
cd ModuleNameThen you need to add to dependencies ModuWeb.dll.
Important: To use HttpContext and other ASP.NET Core types in your module, add a FrameworkReference to your .csproj file:
<ItemGroup>
<!-- Add this to get HttpContext and ASP.NET Core dependencies -->
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<!-- Reference to ModuWeb.dll -->
<Reference Include="ModuWeb">
<HintPath>path/to/ModuWeb.dll</HintPath>
</Reference>
</ItemGroup>This way you don't need to manually add NuGet packages for ASP.NET Core dependencies.
A module must inherit from ModuleBase and override methods such as:
public class HelloWorldModule : ModuleBase
{
public override async Task OnModuleLoad()
{
Map("hello", "GET", HelloWorldHandler);
}
public async Task HelloWorldHandler(HttpContext context)
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("Hello World!");
}
}Map(string path, string method, Func<HttpContext, Task> handler)— maps a route.Handle(...)— receives and routes the request.WithOriginsCors,WithHeadersCors,BlockFailedCorsRequests— specify CORS policies.ModuleName— name of module that will used for some system tools.OnModuleLoad()— optional initialization logic.OnModuleUnLoad()— optional cleanup logic.
Module files may have unique names:
- index.dll — special module name used to handle the main page (/ or /index).
You can also see the examples in examples.
- Dependencies should be placed in
modules/dependencies/. They will be copied automatically. - Modules are loaded into memory. Dependencies only as
- A failed module load is logged but does not crash the host.
- The middleware checks the base API path (from configuration) and maps requests accordingly.
- Empty string into path in Map will mean base url with some method.
After placing a sample DLL in modules/, you can access its route via:
http://localhost:5000/{ModuleName}/{Route}
For example, with a module named HelloWorld:
GET http://localhost:5000/HelloWorld/hello
The example/ folder includes working example modules you can compile and test.
This project is open-source and free to use, modify, and distribute.