From 10fb3c7102ed6928be0de33de85f0e481c8a8473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=BD=E7=AC=94wys?= <46271592+Skymly@users.noreply.github.com> Date: Sun, 19 Jul 2026 21:55:25 +0800 Subject: [PATCH 1/3] Point PluginAssemblies at Configuration extension. Replace the removed AppSettings bridge with an IConfiguration adapter and restore UTF-8 for files corrupted by the prior encoding fix. --- .github/workflows/ci.yml | 52 ++++++++++++++++++- .../Host/Program.cs | 35 +++++++++++-- .../README.md | 4 +- Directory.Build.props | 2 +- Directory.Build.targets | 4 +- README.md | 5 +- build/_build.csproj | 19 ++++++- global.json | 8 ++- 8 files changed, 113 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2f1b81..dd4d149 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1 +1,51 @@ -慮敭›䥃ਊ湥㩶 䘠剏䕃䩟噁十剃偉彔䍁䥔乏当佔也䑏㉅㨴琠畲੥漊㩮 瀠獵㩨 †戠慲据敨㩳嬠慭湩੝†異汬牟煥敵瑳਺††牢湡档獥›浛楡嵮 眠牯晫潬彷楤灳瑡档਺瀊牥業獳潩獮਺†潣瑮湥獴›敲摡ਊ潣据牵敲据㩹 朠潲灵›楣␭筻朠瑩畨⹢潷歲汦睯素⵽笤⁻楧桴扵爮晥素੽†慣据汥椭⵮牰杯敲獳›牴敵ਊ潪獢਺†慳灭敬㩳 †爠湵⵳湯›扵湵畴氭瑡獥ੴ††瑳灥㩳 ††ⴠ渠浡㩥䌠敨正畯⁴敄楳湧慐瑴牥獮⠠楳汢湩⥧ †††甠敳㩳愠瑣潩獮振敨正畯䁴㑶 †††眠瑩㩨 ††††爠灥獯瑩牯㩹匠祫汭⽹敄楳湧慐瑴牥獮 ††††瀠瑡㩨䐠獥杩偮瑡整湲ੳ ††ⴠ渠浡㩥䌠敨正畯⁴敄楳湧慐瑴牥獮匮浡汰獥 †††甠敳㩳愠瑣潩獮振敨正畯䁴㑶 †††眠瑩㩨 ††††瀠瑡㩨䐠獥杩偮瑡整湲⹳慓灭敬ੳ ††ⴠ渠浡㩥匠瑥灵⸠䕎⁔䑓ੋ††††獵獥›捡楴湯⽳敳畴⵰潤湴瑥癀਴††††楷桴਺†††††潤湴瑥瘭牥楳湯›〱〮砮ਊ†††‭慮敭›慃档⁥畎敇⁴慰正条獥 †††甠敳㩳愠瑣潩獮振捡敨癀਴††††楷桴਺†††††慰桴›⽾渮杵瑥瀯捡慫敧ੳ†††††敫㩹␠筻爠湵敮⹲獯素⵽畮敧⵴灤猭浡汰獥␭筻栠獡䙨汩獥✨敄楳湧慐瑴牥獮匮浡汰獥⨯⼪⸪獣牰橯Ⱗ✠敄楳湧慐瑴牥獮匮浡汰獥术潬慢⹬獪湯Ⱗ✠敄楳湧慐瑴牥獮⨯⼪⸪獣牰橯⤧素੽†††††敲瑳牯ⵥ敫獹›੼††††††笤⁻畲湮牥漮⁳絽渭杵瑥搭⵰慳灭敬⵳ †††††␠筻爠湵敮⹲獯素⵽畮敧⵴ਊ†††‭慮敭›畒慳灭敬⁳楶⁡畎敫 †††眠牯楫杮搭物捥潴祲›敄楳湧慐瑴牥獮匮浡汰獥 †††爠湵›潤湴瑥爠湵ⴠ瀭潲敪瑣戠極摬弯畢汩⹤獣牰橯ⴠ‭ⴭ潲瑯⸠ⴠ琭牡敧⁴楃ⴠ挭湯楦畧慲楴湯删汥慥敳� \ No newline at end of file +name: CI + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + samples: + runs-on: ubuntu-latest + steps: + - name: Checkout DesignPatterns (sibling) + uses: actions/checkout@v4 + with: + repository: Skymly/DesignPatterns + path: DesignPatterns + + - name: Checkout DesignPatterns.Samples + uses: actions/checkout@v4 + with: + path: DesignPatterns.Samples + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Cache NuGet packages + uses: actions/cache@v4 + with: + path: ~/.nuget/packages + key: ${{ runner.os }}-nuget-dp-samples-${{ hashFiles('DesignPatterns.Samples/**/*.csproj', 'DesignPatterns.Samples/global.json', 'DesignPatterns/**/*.csproj') }} + restore-keys: | + ${{ runner.os }}-nuget-dp-samples- + ${{ runner.os }}-nuget- + + - name: Run samples via Nuke + working-directory: DesignPatterns.Samples + run: dotnet run --project build/_build.csproj -- --root . --target Ci --configuration Release diff --git a/DesignPatterns.Samples.PluginAssemblies/Host/Program.cs b/DesignPatterns.Samples.PluginAssemblies/Host/Program.cs index e1665ae..32dc7d9 100644 --- a/DesignPatterns.Samples.PluginAssemblies/Host/Program.cs +++ b/DesignPatterns.Samples.PluginAssemblies/Host/Program.cs @@ -1,12 +1,16 @@ using System.Configuration; using Autofac; -using DesignPatterns.Extensions.AppSettings; +using DesignPatterns.Extensions.Configuration; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Primitives; using PluginAssemblies.Sample.Contracts; using PluginAssemblies.Sample.Providers.Alpha; using PluginAssemblies.Sample.Providers.Gamma; var scenario = args.FirstOrDefault() ?? "s1"; -var cardAppSettingsKey = scenario.Equals("s2", StringComparison.OrdinalIgnoreCase) ? "CardMissing" : "Card"; +var cardConfigurationKey = scenario.Equals("s2", StringComparison.OrdinalIgnoreCase) ? "CardMissing" : "Card"; + +IConfiguration configuration = new AppSettingsConfiguration(); var builder = new ContainerBuilder(); builder.RegisterModule(); @@ -38,11 +42,12 @@ if (!RegistryConfiguration.TryResolveConfigured( cardRegistry, - cardAppSettingsKey, + configuration, + cardConfigurationKey, out var card, defaultKey: CardMotionKeys.Alpha)) { - var configuredValue = ConfigurationManager.AppSettings[cardAppSettingsKey]; + var configuredValue = configuration[cardConfigurationKey]; var strategyKey = string.IsNullOrWhiteSpace(configuredValue) ? CardMotionKeys.Alpha : configuredValue; Console.Error.WriteLine( $"Card provider '{strategyKey}' is not registered. Available keys: {cardKeys}. " + @@ -52,19 +57,39 @@ if (!RegistryConfiguration.TryResolveConfigured( fcRegistry, + configuration, "FC", out var fc, defaultKey: FCControlKeys.Gamma) || !RegistryConfiguration.TryResolveConfigured( fcErrorRegistry, + configuration, "FC", out var fcError, defaultKey: FCControlKeys.Gamma)) { - var fcKey = ConfigurationManager.AppSettings["FC"] ?? FCControlKeys.Gamma; + var fcKey = configuration["FC"] ?? FCControlKeys.Gamma; Console.Error.WriteLine($"FC provider '{fcKey}' is not registered for both IFCControl and IFCError."); return 1; } Console.WriteLine($"Card={card!.ProviderName}, FC={fc!.ProviderName}, FCError={fcError!.ProviderName}"); return 0; + +file sealed class AppSettingsConfiguration : IConfiguration +{ + public string? this[string key] + { + get => ConfigurationManager.AppSettings[key]; + set => throw new NotSupportedException(); + } + + public IEnumerable GetChildren() => + throw new NotSupportedException(); + + public IChangeToken GetReloadToken() => + throw new NotSupportedException(); + + public IConfigurationSection GetSection(string key) => + throw new NotSupportedException(); +} diff --git a/DesignPatterns.Samples.PluginAssemblies/README.md b/DesignPatterns.Samples.PluginAssemblies/README.md index 39a83b4..5710e0e 100644 --- a/DesignPatterns.Samples.PluginAssemblies/README.md +++ b/DesignPatterns.Samples.PluginAssemblies/README.md @@ -28,7 +28,7 @@ Each provider assembly emits its own `{Contract}Registry` in the **contract name | **S3** | `dotnet test` in sibling DesignPatterns repo (`UnknownRegistryKeyAnalyzerTests`) or IDE on `Scenarios.InvalidKey` | Diagnostic **DP025** for unknown literal key | | **S4** | `dotnet test` in sibling DesignPatterns repo (`CrossAssemblyRegistryKeyAnalyzerTests`) or IDE on `Scenarios.DuplicateKey` | Diagnostic **DP033** when Alpha and AlphaConflict both register `alpha` | -`Host/App.config` selects `Card=alpha` and `FC=gamma` for S1. The host uses `DesignPatterns.Extensions.AppSettings.RegistryConfiguration` to map those keys to strategy registries (`CardMissing=beta` drives S2). +`Host/App.config` selects `Card=alpha` and `FC=gamma` for S1. The host maps AppSettings into `IConfiguration`, then uses `DesignPatterns.Extensions.Configuration.RegistryConfiguration` to resolve strategy registries (`CardMissing=beta` drives S2). `Scenarios.InvalidKey/InvalidKeyUsage.cs` shows the invalid literal pattern; DP025 is enforced by the DesignPatterns analyzer (IDE or NuGet package). Local sibling `ProjectReference` builds may not surface Info-level diagnostics on the command line — CI runs the analyzer unit test instead. @@ -36,7 +36,7 @@ Each provider assembly emits its own `{Contract}Registry` in the **contract name ## Prerequisites -Sibling [DesignPatterns](https://github.com/Skymly/DesignPatterns) clone with `DesignPatterns.Extensions.Autofac` and `DesignPatterns.Extensions.AppSettings` (merged on `main`). +Sibling [DesignPatterns](https://github.com/Skymly/DesignPatterns) clone with `DesignPatterns.Extensions.Autofac` and `DesignPatterns.Extensions.Configuration` (merged on `main`). ```powershell cd DesignPatterns.Samples diff --git a/Directory.Build.props b/Directory.Build.props index fc1ce12..0093733 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -15,7 +15,7 @@ $(DesignPatternsRepoRoot)/DesignPatterns.Extensions.DependencyInjection/build/DesignPatterns.Extensions.DependencyInjection.targets $(DesignPatternsRepoRoot)/DesignPatterns.Extensions.Autofac/DesignPatterns.Extensions.Autofac.csproj $(DesignPatternsRepoRoot)/DesignPatterns.Extensions.Autofac/build/DesignPatterns.Extensions.Autofac.targets - $(DesignPatternsRepoRoot)/DesignPatterns.Extensions.AppSettings/DesignPatterns.Extensions.AppSettings.csproj + $(DesignPatternsRepoRoot)/DesignPatterns.Extensions.Configuration/DesignPatterns.Extensions.Configuration.csproj $(DesignPatternsRepoRoot)/DesignPatterns.Analyzers/DesignPatterns.Analyzers.csproj diff --git a/Directory.Build.targets b/Directory.Build.targets index d2ab79e..0532135 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -33,7 +33,7 @@ - + Analyzer false @@ -70,7 +70,7 @@ - + diff --git a/README.md b/README.md index c2c73a2..932e030 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Equivalent: `dotnet run --project build/_build.csproj -- --root . --target Ci -- | **DesignPatterns.Samples.GenerateSingleton** | `[GenerateSingleton]` lazy singleton | | **DesignPatterns.Samples.DependencyInjection** | `RegisterDi` for Strategy / Factory / Handler | | **DesignPatterns.Samples.State** | Manual `TransitionTableBuilder` + `[StateMachine]` / `[Transition]` order lifecycle; guard predicates; entry/exit actions; `IStateMachine` wrapper; `TransitionTrace` | -| **DesignPatterns.Samples.PluginAssemblies** | Multi-assembly `[RegisterStrategy]` + `RegisterAutofac` + `RegistryConfiguration` (AppSettings; see nested [README](DesignPatterns.Samples.PluginAssemblies/README.md)) | +| **DesignPatterns.Samples.PluginAssemblies** | Multi-assembly `[RegisterStrategy]` + `RegisterAutofac` + `RegistryConfiguration` (`IConfiguration`; see nested [README](DesignPatterns.Samples.PluginAssemblies/README.md)) | ## Published NuGet consumption @@ -67,8 +67,7 @@ the package-backed samples, set `UseLocalDesignPatterns=false`: dotnet run --project build/_build.csproj -- --root . --target Ci --configuration Release --use-local-design-patterns false ``` -The `PluginAssemblies` sample also uses the non-packable `AppSettings` extension -from the sibling repository and therefore remains sibling-layout-only. +`PluginAssemblies` needs `Skymly.DesignPatterns.Extensions.Configuration` (plus Autofac). Until that extension is published alongside the next preview, run it with the sibling local clone (`UseLocalDesignPatterns=true`, default). ## Related diff --git a/build/_build.csproj b/build/_build.csproj index b4ba03a..258d0b1 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -1 +1,18 @@ -值潲敪瑣匠此∽楍牣獯景⹴䕎⹔摓≫ਾ 㰠牐灯牥祴片畯㹰 †㰠畏灴瑵祔数䔾數⼼畏灴瑵祔数ਾ††吼牡敧䙴慲敭潷歲渾瑥〱〮⼼慔杲瑥牆浡睥牯㹫 †㰠浉汰捩瑩獕湩獧放慮汢㱥䤯灭楬楣啴楳杮㹳 †㰠畎汬扡敬放慮汢㱥丯汵慬汢㹥 †㰠畎敫敔敬敭牴噹牥楳湯ㄾ⼼畎敫敔敬敭牴噹牥楳湯ਾ††䤼偳捡慫汢㹥慦獬㱥䤯偳捡慫汢㹥 㰠倯潲数瑲䝹潲灵ਾ 㰠瑉浥片畯㹰 †㰠慐正条剥晥牥湥散䤠据畬敤∽畎敫䌮浯潭≮嘠牥楳湯∽〱ㄮ〮•㸯 †㰠慐正条剥晥牥湥散䤠据畬敤∽畎敇⹴慐正条湩≧嘠牥楳湯∽⸶㐱㌮•牐癩瑡䅥獳瑥㵳愢汬•㸯 †㰠慐正条剥晥牥湥散䤠据畬敤∽祓瑳浥匮捥牵瑩⹹牃灹潴牧灡票堮汭•敖獲潩㵮ㄢ⸰⸰〱•牐癩瑡䅥獳瑥㵳愢汬•㸯 㰠䤯整䝭潲灵ਾ㰊倯潲敪瑣ਾ \ No newline at end of file + + + + Exe + net10.0 + enable + enable + 1 + false + + + + + + + + + diff --git a/global.json b/global.json index 4648027..44fbb79 100644 --- a/global.json +++ b/global.json @@ -1 +1,7 @@ -੻†猢此㨢笠 †∠敶獲潩≮›ㄢ⸰⸰〳∱ਬ††爢汯䙬牯慷摲㨢∠慬整瑳慍潪≲ਬ††愢汬睯牐牥汥慥敳㨢映污敳 素紊� \ No newline at end of file +{ + "sdk": { + "version": "10.0.301", + "rollForward": "latestMajor", + "allowPrerelease": false + } +} From cfe5ec349c1a0d59d18014e9e8605e8676d4e984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=BD=E7=AC=94wys?= <46271592+Skymly@users.noreply.github.com> Date: Sun, 19 Jul 2026 22:01:49 +0800 Subject: [PATCH 2/3] Checkout sibling DesignPatterns by matching branch name in CI. Paired PRs share a branch name; this avoids pulling a still-corrupted sibling main during the encoding recovery. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd4d149..2a5118f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,8 @@ jobs: uses: actions/checkout@v4 with: repository: Skymly/DesignPatterns + # Paired PR branches share a name; main pushes use main. + ref: ${{ github.head_ref || github.ref_name }} path: DesignPatterns - name: Checkout DesignPatterns.Samples From 330c58487cc64a7fed9b0b924a5132898421a258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=BD=E7=AC=94wys?= <46271592+Skymly@users.noreply.github.com> Date: Mon, 20 Jul 2026 23:14:04 +0800 Subject: [PATCH 3/3] Pin samples to 0.2.3-preview2 packages Align published NuGet consumption notes with the Configuration extension release. Co-authored-by: Cursor --- Directory.Build.props | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 0093733..13bf5f5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 0.2.3-preview1 + 0.2.3-preview2 $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../DesignPatterns')) true diff --git a/README.md b/README.md index 932e030..b66b05f 100644 --- a/README.md +++ b/README.md @@ -60,14 +60,14 @@ Equivalent: `dotnet run --project build/_build.csproj -- --root . --target Ci -- ## Published NuGet consumption -The published `0.2.3-preview1` package is pinned in `Directory.Build.props`. To run +The published `0.2.3-preview2` package is pinned in `Directory.Build.props`. To run the package-backed samples, set `UseLocalDesignPatterns=false`: ```powershell dotnet run --project build/_build.csproj -- --root . --target Ci --configuration Release --use-local-design-patterns false ``` -`PluginAssemblies` needs `Skymly.DesignPatterns.Extensions.Configuration` (plus Autofac). Until that extension is published alongside the next preview, run it with the sibling local clone (`UseLocalDesignPatterns=true`, default). +`PluginAssemblies` also needs `Skymly.DesignPatterns.Extensions.Autofac` and `Skymly.DesignPatterns.Extensions.Configuration` (same version pin). ## Related