| | | 1 | | using System.Reflection; |
| | | 2 | | using Microsoft.AspNetCore.Server.Kestrel.Core; |
| | | 3 | | namespace Kestrun.Hosting.Options; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Provides extension methods for copying configuration between <see cref="KestrelServerOptions"/> instances. |
| | | 7 | | /// </summary> |
| | | 8 | | public static class KestrelOptionsExtensions |
| | | 9 | | { |
| | | 10 | | /// <summary> |
| | | 11 | | /// Shallow-copies every writable property from <paramref name="src"/> to <paramref name="dest"/>, |
| | | 12 | | /// then deep-copies the nested <see cref="KestrelServerLimits"/>. |
| | | 13 | | /// A small “skip” list prevents us from overwriting framework internals. |
| | | 14 | | /// </summary> |
| | | 15 | | public static void CopyFromTemplate(this KestrelServerOptions dest, |
| | | 16 | | KestrelServerOptions src) |
| | | 17 | | { |
| | 58 | 18 | | if (dest is null || src is null) |
| | | 19 | | { |
| | 2 | 20 | | throw new ArgumentNullException(); |
| | | 21 | | } |
| | | 22 | | |
| | 56 | 23 | | var skip = new HashSet<string> |
| | 56 | 24 | | { |
| | 56 | 25 | | nameof(KestrelServerOptions.ApplicationServices), // owned by the WebHost |
| | 56 | 26 | | //nameof(KestrelServerOptions.ListenOptions) // you add those yourself |
| | 56 | 27 | | }; |
| | | 28 | | |
| | | 29 | | // ── 1. copy all simple writable props ─────────────────────────────── |
| | 1456 | 30 | | foreach (var p in typeof(KestrelServerOptions) |
| | 56 | 31 | | .GetProperties(BindingFlags.Public | BindingFlags.Instance)) |
| | | 32 | | { |
| | 672 | 33 | | if (!p.CanRead || !p.CanWrite) |
| | | 34 | | { |
| | | 35 | | continue; // read-only |
| | | 36 | | } |
| | | 37 | | |
| | 616 | 38 | | if (p.GetIndexParameters().Length > 0) |
| | | 39 | | { |
| | | 40 | | continue; // indexer |
| | | 41 | | } |
| | | 42 | | |
| | 616 | 43 | | if (skip.Contains(p.Name)) |
| | | 44 | | { |
| | | 45 | | continue; // infrastructure |
| | | 46 | | } |
| | | 47 | | |
| | 560 | 48 | | p.SetValue(dest, p.GetValue(src)); |
| | | 49 | | } |
| | | 50 | | |
| | | 51 | | // ── 2. deep-copy the Limits object (property itself is read-only) ── |
| | 56 | 52 | | CopyLimits(dest.Limits, src.Limits); |
| | 56 | 53 | | } |
| | | 54 | | |
| | | 55 | | private static void CopyLimits(KestrelServerLimits dest, KestrelServerLimits src) |
| | | 56 | | { |
| | 1680 | 57 | | foreach (var p in typeof(KestrelServerLimits) |
| | 56 | 58 | | .GetProperties(BindingFlags.Public | BindingFlags.Instance)) |
| | | 59 | | { |
| | 784 | 60 | | if (!p.CanRead || !p.CanWrite) |
| | | 61 | | { |
| | | 62 | | continue; |
| | | 63 | | } |
| | | 64 | | |
| | 672 | 65 | | if (p.GetIndexParameters().Length > 0) |
| | | 66 | | { |
| | | 67 | | continue; |
| | | 68 | | } |
| | | 69 | | |
| | 672 | 70 | | p.SetValue(dest, p.GetValue(src)); |
| | | 71 | | } |
| | 56 | 72 | | } |
| | | 73 | | } |