A powerful .NET 8 library for compiling and executing C# code dynamically at runtime. This engine supports loading modules from strings or files, managing them with different lifetimes (Singleton, Scoped, Transient), and provides a ready-to-use API controller for easy integration into ASP.NET Core applications. It's designed for building extensible systems like plugin platforms or dynamic rule engines.
$ dotnet add package Linh.CodeEngineLinh.CodeEngine is a powerful and flexible .NET 8 library that allows you to compile and execute C# code dynamically at runtime. Built on top of the Roslyn compiler platform, this library is the perfect solution for building extensible systems, such as plugin platforms, rule engines, or scripting systems.
The library is designed for seamless integration into ASP.NET Core applications.
In many complex systems, business logic often changes (e.g., promotional formulas, approval workflows, payroll calculations). Hard-coding this logic requires code changes, a full application rebuild, and a new deployment for every update.
Linh.CodeEngine solves this by enabling you to:
Singleton, Scoped, and Transient lifetimes for dynamic modules, deeply integrating with ASP.NET Core's Dependency Injection.IDynamicAction<TIn, TOut>) for type safety.Reflection for classes that don't implement the interface, with full support for both synchronous and asynchronous (async Task) methods.AssemblyLoadContext to load and unload assemblies, preventing conflicts and memory leaks.Storage Provider for the File System and can be easily extended for EF Core or other databases.DynamicCodeAdminController to manage code modules out of the box.You can install the package from the NuGet Gallery.
dotnet add package Linh.CodeEngine
Integrating the engine into an ASP.NET Core application involves two main steps: Service Registration and Application Configuration.
In Program.cs, register the engine's services.
Add the AddDynamicCodeEngineWithFileSystem extension method to your service configuration.
// Program.cs
using Linh.CodeEngine.Extensions; // Add this using directive
var builder = WebApplication.CreateBuilder(args);
// Add your other services...
builder.Services.AddControllers();
// --- 1. REGISTER LINH.CODEENGINE SERVICES ---
var storagePath = Path.Combine(builder.Environment.ContentRootPath, "DynamicModules");
builder.Services.AddDynamicCodeEngineWithFileSystem(storagePath);
var app = builder.Build();
// ...
Configure the engine to load modules on application startup.
Immediately after the app is built, call the ConfigureCodeEngine extension method. This is an asynchronous call that will load all active modules from your chosen storage provider.
// Program.cs (continued)
var app = builder.Build();
// --- 2. CONFIGURE AND LOAD MODULES ON STARTUP ---
await app.ConfigureCodeEngine();
// Configure your HTTP request pipeline
if (app.Environment.IsDevelopment())
{
// ...
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Use DynamicCodeManager in your application.
Once configured, you can access the DynamicCodeManager via Dependency Injection (recommended) or through the globally available singleton instance.
Option 1: Using Dependency Injection (Recommended)
[ApiController]
[Route("[controller]")]
public class MyBusinessController : ControllerBase
{
private readonly DynamicCodeManager _codeManager;
// Inject via the constructor
public MyBusinessController(DynamicCodeManager codeManager)
{
_codeManager = codeManager;
}
[HttpGet("calculate-tax")]
public IActionResult CalculateTax([FromQuery] decimal orderAmount)
{
var result = _codeManager.Execute<decimal, decimal>(
"SimpleTaxCalculator",
orderAmount
);
if (result.IsSuccess)
{
return Ok(new { TaxAmount = result.Output });
}
return BadRequest(result.ErrorMessage);
}
}
Option 2: Using the Singleton Instance (if injection is not possible)
public class SomeOtherService
{
public void DoSomething()
{
// Access directly via the Singleton
var codeManager = Singleton<DynamicCodeManager>.Instance;
var result = codeManager.Execute<string, bool>("MyValidationRule", "some-input");
// ...
}
}
This project is licensed under the MIT License. See the LICENSE file for details.
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Made with ❤️ by Linh Nguyen.