< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Hosting.KestrunHostRazorExtensions
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Hosting/KestrunHostRazorExtensions.cs
Tag: Kestrun/Kestrun@9d3a582b2d63930269564a7591aa77ef297cadeb
Line coverage
56%
Covered lines: 70
Uncovered lines: 53
Coverable lines: 123
Total lines: 219
Line coverage: 56.9%
Branch coverage
31%
Covered branches: 12
Total branches: 38
Branch coverage: 31.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddPowerShellRazorPages(...)33.33%7675%
AddPowerShellRazorPages(...)100%11100%
AddPowerShellRazorPages(...)100%11100%
IsManaged(...)100%210%
AddPowerShellRazorPages(...)9.09%1332238.88%
AddRazorPages(...)66.66%6686.66%
AddRazorPages(...)100%44100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Hosting/KestrunHostRazorExtensions.cs

#LineLine coverage
 1using System.Reflection;
 2using Kestrun.Razor;
 3using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation;
 4using Microsoft.AspNetCore.Mvc.RazorPages;
 5using Microsoft.Extensions.FileProviders;
 6using Serilog.Events;
 7
 8namespace Kestrun.Hosting;
 9
 10/// <summary>
 11/// Provides extension methods for adding PowerShell and Razor Pages to a KestrunHost.
 12/// </summary>
 13public static class KestrunHostRazorExtensions
 14{
 15    /// <summary>
 16    /// Adds PowerShell Razor Pages to the application.
 17    /// This middleware allows you to serve Razor Pages using PowerShell scripts.
 18    /// </summary>
 19    /// <param name="host">The KestrunHost instance to add Razor Pages to.</param>
 20    /// <param name="routePrefix">The route prefix to use for the PowerShell Razor Pages.</param>
 21    /// <param name="cfg">Configuration options for the Razor Pages.</param>
 22    /// <returns>The current KestrunHost instance.</returns>
 23    public static KestrunHost AddPowerShellRazorPages(this KestrunHost host, PathString? routePrefix, RazorPagesOptions?
 24    {
 325        if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 26        {
 327            host.HostLogger.Debug("Adding PowerShell Razor Pages with route prefix: {RoutePrefix}, config: {@Config}", r
 28        }
 29
 330        return AddPowerShellRazorPages(host, routePrefix, dest =>
 331            {
 032                if (cfg != null)
 333                {
 334                    // simple value properties are fine
 035                    dest.RootDirectory = cfg.RootDirectory;
 336
 337                    // copy conventions one‑by‑one (collection is read‑only)
 038                    foreach (var c in cfg.Conventions)
 339                    {
 040                        dest.Conventions.Add(c);
 341                    }
 342                }
 343            });
 44    }
 45
 46    /// <summary>
 47    /// Adds PowerShell Razor Pages to the application.
 48    /// This middleware allows you to serve Razor Pages using PowerShell scripts.
 49    /// </summary>
 50    /// <param name="host">The KestrunHost instance to add Razor Pages to.</param>
 51    /// <param name="routePrefix">The route prefix to use for the PowerShell Razor Pages.</param>
 52    /// <returns>The current KestrunHost instance.</returns>
 53    public static KestrunHost AddPowerShellRazorPages(this KestrunHost host, PathString? routePrefix) =>
 154        AddPowerShellRazorPages(host: host, routePrefix: routePrefix, cfg: null as RazorPagesOptions);
 55
 56    /// <summary>
 57    /// Adds PowerShell Razor Pages to the application with default configuration and no route prefix.
 58    /// </summary>
 59    /// <param name="host">The KestrunHost instance to add Razor Pages to.</param>
 60    /// <returns>The current KestrunHost instance.</returns>
 61    public static KestrunHost AddPowerShellRazorPages(this KestrunHost host) =>
 162        AddPowerShellRazorPages(host: host, routePrefix: null, cfg: null as RazorPagesOptions);
 63
 64    // helper: true  ⇢ file contains managed metadata
 65    private static bool IsManaged(string path)
 66    {
 067        try { _ = AssemblyName.GetAssemblyName(path); return true; }
 068        catch { return false; }          // native ⇒ BadImageFormatException
 069    }
 70    /// <summary>
 71    /// Adds PowerShell Razor Pages to the application.
 72    /// This middleware allows you to serve Razor Pages using PowerShell scripts.
 73    /// </summary>
 74    /// <param name="host">The KestrunHost instance to add Razor Pages to.</param>
 75    /// <param name="routePrefix">The route prefix to use for the PowerShell Razor Pages.</param>
 76    /// <param name="cfg">Configuration options for the Razor Pages.</param>
 77    /// <returns>The current KestrunHost instance.</returns>
 78    public static KestrunHost AddPowerShellRazorPages(this KestrunHost host, PathString? routePrefix, Action<RazorPagesO
 79    {
 380        if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 81        {
 382            host.HostLogger.Debug("Adding PowerShell Razor Pages with route prefix: {RoutePrefix}, config: {@Config}", r
 83        }
 84
 385        _ = host.AddService(services =>
 386        {
 087            var env = host.Builder.Environment;
 088            if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 389            {
 090                host.HostLogger.Debug("Adding PowerShell Razor Pages to the service with route prefix: {RoutePrefix}", r
 391            }
 392
 093            _ = services.AddRazorPages().AddRazorRuntimeCompilation();
 394
 395            // ── NEW: feed Roslyn every assembly already loaded ──────────
 396            //      var env = builder.Environment;                  // or app.Environment
 097            var pagesRoot = Path.Combine(env.ContentRootPath, "Pages");
 398
 099            _ = services.Configure<MvcRazorRuntimeCompilationOptions>(opts =>
 0100            {
 0101                // 1️⃣  everything that’s already loaded and managed
 0102                foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()
 0103                                    .Where(a => !a.IsDynamic && IsManaged(a.Location)))
 0104                {
 0105                    opts.AdditionalReferencePaths.Add(asm.Location);
 0106                }
 0107
 0108                // 2️⃣  managed DLLs from the .NET-8 shared-framework folder
 0109                var coreDir = Path.GetDirectoryName(typeof(object).Assembly.Location)!;   // e.g. …\dotnet\shared\Micros
 0110                foreach (var dll in Directory.EnumerateFiles(coreDir, "*.dll")
 0111                                                .Where(IsManaged))
 0112                {
 0113                    opts.AdditionalReferencePaths.Add(dll);
 0114                }
 0115
 0116                // 3️⃣  (optional) watch your project’s Pages folder so edits hot-reload
 0117                var pagesRoot = Path.Combine(host.Builder.Environment.ContentRootPath, "Pages");
 0118                if (Directory.Exists(pagesRoot))
 0119                {
 0120                    opts.FileProviders.Add(new PhysicalFileProvider(pagesRoot));
 0121                }
 0122            });
 3123        });
 124
 3125        return host.Use(app =>
 3126        {
 0127            ArgumentNullException.ThrowIfNull(host.RunspacePool);
 0128            if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 3129            {
 0130                host.HostLogger.Debug("Adding PowerShell Razor Pages middleware with route prefix: {RoutePrefix}", route
 3131            }
 3132
 0133            if (routePrefix.HasValue)
 3134            {
 3135                // ── /ps  (or whatever prefix) ──────────────────────────────
 0136                _ = app.Map(routePrefix.Value, branch =>
 0137                {
 0138                    _ = branch.UsePowerShellRazorPages(host.RunspacePool);   // bridge
 0139                    _ = branch.UseRouting();                             // add routing
 0140                    _ = branch.UseEndpoints(e => e.MapRazorPages());     // map pages
 0141                });
 3142            }
 3143            else
 3144            {
 3145                // ── mounted at root ────────────────────────────────────────
 0146                _ = app.UsePowerShellRazorPages(host.RunspacePool);          // bridge
 0147                _ = app.UseRouting();                                    // add routing
 0148                _ = app.UseEndpoints(e => e.MapRazorPages());            // map pages
 3149            }
 3150
 0151            if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 3152            {
 0153                host.HostLogger.Debug("PowerShell Razor Pages middleware added with route prefix: {RoutePrefix}", routeP
 3154            }
 3155        });
 156    }
 157
 158
 159    /// <summary>
 160    /// Adds Razor Pages to the application.
 161    /// </summary>
 162    /// <param name="host">The KestrunHost instance to add Razor Pages to.</param>
 163    /// <param name="cfg">The configuration options for Razor Pages.</param>
 164    /// <returns>The current KestrunHost instance.</returns>
 165    public static KestrunHost AddRazorPages(this KestrunHost host, RazorPagesOptions? cfg)
 166    {
 1167        if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 168        {
 1169            host.HostLogger.Debug("Adding Razor Pages from source: {Source}", cfg);
 170        }
 171
 1172        if (cfg == null)
 173        {
 0174            return host.AddRazorPages(); // no config, use defaults
 175        }
 176
 1177        return host.AddRazorPages(dest =>
 1178            {
 1179                // simple value properties are fine
 1180                dest.RootDirectory = cfg.RootDirectory;
 1181
 1182                // copy conventions one‑by‑one (collection is read‑only)
 2183                foreach (var c in cfg.Conventions)
 1184                {
 0185                    dest.Conventions.Add(c);
 1186                }
 2187            });
 188    }
 189
 190    /// <summary>
 191    /// Adds Razor Pages to the application.
 192    /// This overload allows you to specify configuration options.
 193    /// If you need to configure Razor Pages options, use the other overload.
 194    /// </summary>
 195    /// <param name="host">The KestrunHost instance to add Razor Pages to.</param>
 196    /// <param name="cfg">The configuration options for Razor Pages.</param>
 197    /// <returns>The current KestrunHost instance.</returns>
 198    public static KestrunHost AddRazorPages(this KestrunHost host, Action<RazorPagesOptions>? cfg = null)
 199    {
 3200        if (host.HostLogger.IsEnabled(LogEventLevel.Debug))
 201        {
 3202            host.HostLogger.Debug("Adding Razor Pages with configuration: {Config}", cfg);
 203        }
 204
 3205        return host.AddService(services =>
 3206        {
 3207            var mvc = services.AddRazorPages();         // returns IMvcBuilder
 3208
 3209            if (cfg != null)
 3210            {
 2211                _ = mvc.AddRazorPagesOptions(cfg);          // ← the correct extension
 3212            }
 3213            //  —OR—
 3214            // services.Configure(cfg);                 // also works
 3215        })
 3216         // optional: automatically map Razor endpoints after Build()
 6217         .Use(app => ((IEndpointRouteBuilder)app).MapRazorPages());
 218    }
 219}