Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const enSidebar = [
{ text: 'Event Aggregator', link: '/event-aggregator' },
{ text: 'State transition table', link: '/state-transition-table' },
{ text: 'Dependency Injection', link: '/dependency-injection' },
{ text: 'Configuration', link: '/configuration' },
],
},
{ text: 'Diagnostics', link: '/diagnostics' },
Expand All @@ -47,6 +48,7 @@ const zhSidebar = [
{ text: 'Event Aggregator', link: '/zh/event-aggregator' },
{ text: 'State 转换表', link: '/zh/state-transition-table' },
{ text: '依赖注入', link: '/zh/dependency-injection' },
{ text: '配置桥接', link: '/zh/configuration' },
],
},
{ text: '诊断', link: '/zh/diagnostics' },
Expand Down
94 changes: 94 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Configuration

Package: **`Skymly.DesignPatterns.Extensions.Configuration`**

Maps **`IConfiguration`** string values to **`IStrategyRegistry<string, TContract>`** lookups — useful when a host selects a strategy implementation by configuration key instead of a hand-written `switch`.

Works with generated `{Contract}Registry` / `{Contract}Keys` from `[RegisterStrategy]` (see [Strategy](./strategy.md)).

## Install

Not included in the `Skymly.DesignPatterns` meta package:

```powershell
dotnet add package Skymly.DesignPatterns.Extensions.Configuration --version 0.2.3-preview2
```

```xml
<PackageReference Include="Skymly.DesignPatterns.Extensions.Configuration" Version="0.2.3-preview2" />
```

Targets: `netstandard2.0` and `net8.0`. Depends on `Microsoft.Extensions.Configuration.Abstractions`.

## API

```csharp
using DesignPatterns.Extensions.Configuration;
using Microsoft.Extensions.Configuration;

IConfiguration configuration = /* host configuration */;

// Throws RegistryConfigurationException when the key cannot be resolved.
var card = RegistryConfiguration.ResolveConfigured(
CardMotionRegistry.Instance,
configuration,
configurationKey: "Card",
defaultKey: CardMotionKeys.Alpha);

// Non-throwing variant.
if (RegistryConfiguration.TryResolveConfigured(
CardMotionRegistry.Instance,
configuration,
"Card",
out var motion,
defaultKey: CardMotionKeys.Alpha))
{
// use motion
}
```

### Resolution order

1. Read `IConfiguration[configurationKey]`.
2. When the value is missing or whitespace, use `defaultKey` when provided.
3. Call `registry.TryGet(strategyKey, out implementation)`.

Prefer `{Contract}Keys` constants for `defaultKey` so call sites stay DP025-safe.

### Failure messages

`RegistryConfigurationException` includes the configuration key, the configured value (or default), and the registry `Keys` list:

```text
Configuration key 'Card' has value 'beta' which is not registered. Registered keys: alpha, gamma.
```

## Host example

```csharp
using DesignPatterns.Extensions.Configuration;
using Microsoft.Extensions.Configuration;

var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();

var card = RegistryConfiguration.ResolveConfigured(
CardMotionRegistry.Instance,
configuration,
"Card",
defaultKey: CardMotionKeys.Alpha);
```

## Legacy App.config hosts

There is **no** dedicated `ConfigurationManager.AppSettings` extension package. Map AppSettings into `IConfiguration` in the host (an indexer adapter is enough for `RegistryConfiguration`), then call the same API.

See the [PluginAssemblies sample host](https://github.com/Skymly/DesignPatterns.Samples/tree/main/DesignPatterns.Samples.PluginAssemblies/Host) for a minimal adapter, and [Samples](./samples.md) for NuGet vs sibling consumption.

## Related

- [Strategy](./strategy.md)
- [Dependency injection](./dependency-injection.md) (Autofac / MSDI)
- [Diagnostics](./diagnostics.md) (DP025, DP033)
- Maintainer notes: [Configuration.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/Configuration.md), [PluginAssemblies.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PluginAssemblies.md)
11 changes: 7 additions & 4 deletions docs/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dependency Injection

Package: **`DesignPatterns.Extensions.DependencyInjection`**
Package: **`Skymly.DesignPatterns.Extensions.DependencyInjection`**

## Overview

Expand Down Expand Up @@ -71,11 +71,14 @@ Set `DesignPatternsSampleKind=DependencyInjection` in sample projects for the sh

## Note on meta package

The core **`Skymly.DesignPatterns`** NuGet meta package does **not** include the DI extension; reference `DesignPatterns.Extensions.DependencyInjection` from the main repo (sibling project) until a separate package is published.
The core **`Skymly.DesignPatterns`** NuGet meta package does **not** include DI or Autofac extensions. Install them separately from nuget.org:

- [`Skymly.DesignPatterns.Extensions.DependencyInjection`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.DependencyInjection)
- [`Skymly.DesignPatterns.Extensions.Autofac`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.Autofac)

## Autofac integration

The **`DesignPatterns.Extensions.Autofac`** package provides Autofac integration symmetric to the MSDI `RegisterDi` pattern. When referenced, the source generator emits `RegisterAutofac(ContainerBuilder)` and `Create(ILifetimeScope)` methods for Strategy, Factory, Handler, and State registries.
The **`Skymly.DesignPatterns.Extensions.Autofac`** package provides Autofac integration symmetric to the MSDI `RegisterDi` pattern. When referenced, the source generator emits `RegisterAutofac(ContainerBuilder)` and `Create(ILifetimeScope)` methods for Strategy, Factory, Handler, and State registries.

```csharp
var builder = new ContainerBuilder();
Expand All @@ -89,4 +92,4 @@ var registry = container.Resolve<IStrategyRegistry<string, IPaymentStrategy>>();
- `sharing` — `InstanceSharing.Shared` (default, `SingleInstance()`) or `InstanceSharing.None` (`InstancePerDependency()`)
- `serviceKey` — optional key for keyed registration

The Autofac extension can be referenced alongside `DesignPatterns.Extensions.DependencyInjection` — both `RegisterDi` and `RegisterAutofac` methods are generated. The Autofac extension is **not** included in the meta package; reference it separately.
The Autofac extension can be referenced alongside `Skymly.DesignPatterns.Extensions.DependencyInjection` — both `RegisterDi` and `RegisterAutofac` methods are generated. The Autofac extension is **not** included in the meta package; reference it separately.
2 changes: 1 addition & 1 deletion docs/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ See also [Registry key conventions](./registry-key-conventions.md).

**Fix:** use distinct keys per provider assembly, or reference only one provider per contract dimension. Duplicate keys within a **single** assembly remain **DP003** (generator).

See [Plugin assemblies sample](https://github.com/Skymly/DesignPatterns.Samples/tree/main/DesignPatterns.Samples.PluginAssemblies) and the main repo [PluginAssemblies.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PluginAssemblies.md).
See [Plugin assemblies sample](https://github.com/Skymly/DesignPatterns.Samples/tree/main/DesignPatterns.Samples.PluginAssemblies), the main repo [PluginAssemblies.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PluginAssemblies.md), and [Configuration](./configuration.md).

## State transition table (DP026–DP031) {#state-transition-table-dp026-dp031}

Expand Down
14 changes: 7 additions & 7 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@
The meta package is published as **`Skymly.DesignPatterns`** on [nuget.org](https://www.nuget.org/packages/Skymly.DesignPatterns). C# namespaces remain `DesignPatterns.*`.

```xml
<PackageReference Include="Skymly.DesignPatterns" Version="0.2.3-preview1" />
<PackageReference Include="Skymly.DesignPatterns" Version="0.2.3-preview2" />
```

Or from the command line:

```powershell
dotnet add package Skymly.DesignPatterns --version 0.2.3-preview1
dotnet add package Skymly.DesignPatterns --version 0.2.3-preview2
```

::: warning Early preview
Public APIs, generated code, and `DP###` diagnostics are **not stable** yet. Pin the package version or a Git commit until a stability announcement.
:::

**Optional DI:** the DI integrations are separate packages and are not included in the meta package:
**Optional extensions** (not included in the meta package):

```powershell
dotnet add package Skymly.DesignPatterns.Extensions.DependencyInjection --version 0.2.3-preview1
# Or, when using Autofac:
dotnet add package Skymly.DesignPatterns.Extensions.Autofac --version 0.2.3-preview1
dotnet add package Skymly.DesignPatterns.Extensions.DependencyInjection --version 0.2.3-preview2
dotnet add package Skymly.DesignPatterns.Extensions.Autofac --version 0.2.3-preview2
dotnet add package Skymly.DesignPatterns.Extensions.Configuration --version 0.2.3-preview2
```

See [Dependency injection](./dependency-injection.md).
See [Dependency injection](./dependency-injection.md) and [Configuration](./configuration.md).

## Clone layout (contributors)

Expand Down
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ features:
## Status

::: warning Early preview
Public APIs, generated code shapes, and diagnostic IDs are **not stable** yet. Install [`Skymly.DesignPatterns`](https://www.nuget.org/packages/Skymly.DesignPatterns) `0.2.3-preview1` from nuget.org, or use a sibling clone / pin a commit until a stability announcement.
Public APIs, generated code shapes, and diagnostic IDs are **not stable** yet. Install [`Skymly.DesignPatterns`](https://www.nuget.org/packages/Skymly.DesignPatterns) `0.2.3-preview2` from nuget.org, or use a sibling clone / pin a commit until a stability announcement.
:::

## Where to read next

| Page | Purpose |
|------|---------|
| [Getting started](./getting-started.md) | Clone layout, build, and first attribute |
| [Configuration](./configuration.md) | `IConfiguration` → strategy registry bridge |
| [Samples](./samples.md) | Runnable [DesignPatterns.Samples](https://github.com/Skymly/DesignPatterns.Samples) repo |
| [Diagnostics](./diagnostics.md) | DP### compiler messages |
| [Reference](./reference.md) | Repositories and packages |
Expand Down
13 changes: 9 additions & 4 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@

| Package ID | Version | Contents |
|------------|-------------------|----------|
| [`Skymly.DesignPatterns`](https://www.nuget.org/packages/Skymly.DesignPatterns) | `0.2.3-preview1` | Meta package — runtime + source generator + analyzers + code fixes |
| [`Skymly.DesignPatterns.Extensions.DependencyInjection`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.DependencyInjection) | `0.2.3-preview1` | MSDI extensions + `RegisterDi` generation |
| [`Skymly.DesignPatterns.Extensions.Autofac`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.Autofac) | `0.2.3-preview1` | Autofac extensions + `RegisterAutofac` generation |
| [`Skymly.DesignPatterns`](https://www.nuget.org/packages/Skymly.DesignPatterns) | `0.2.3-preview2` | Meta package — runtime + source generator + analyzers + code fixes |
| [`Skymly.DesignPatterns.Extensions.DependencyInjection`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.DependencyInjection) | `0.2.3-preview2` | MSDI extensions + `RegisterDi` generation |
| [`Skymly.DesignPatterns.Extensions.Autofac`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.Autofac) | `0.2.3-preview2` | Autofac extensions + `RegisterAutofac` generation |
| [`Skymly.DesignPatterns.Extensions.Configuration`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.Configuration) | `0.2.3-preview2` | `IConfiguration` → strategy `RegistryConfiguration` |

```xml
<PackageReference Include="Skymly.DesignPatterns" Version="0.2.3-preview1" />
<PackageReference Include="Skymly.DesignPatterns" Version="0.2.3-preview2" />
```

::: info Deprecated GitHub-only IDs
Expand All @@ -33,6 +34,8 @@ Do not use the old GitHub Packages ID `DesignPatterns` (`0.1.0-preview1` / `prev
| `DesignPatterns.Analyzers` / `DesignPatterns.CodeFixes` | DP006, DP023, DP024, DP025, DP033, DP036, DP044 |
| `DesignPatterns.Diagnostics` | DP### ID constants |
| `DesignPatterns.Extensions.DependencyInjection` | MSDI + DI targets |
| `DesignPatterns.Extensions.Autofac` | Autofac + `RegisterAutofac` targets |
| `DesignPatterns.Extensions.Configuration` | `IConfiguration` → strategy registry bridge |
| `DesignPatterns.Package` | NuGet meta package (`PackageId=Skymly.DesignPatterns`) |
| `eng/nuget-smoke/MetaPackage.Consumer` | End-to-end NuGet consumer smoke test |

Expand All @@ -47,6 +50,8 @@ Deep design notes remain in the main repo:
- [docs/README.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/README.md) — internal doc index
- [docs/DEVELOPMENT.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/DEVELOPMENT.md)
- [docs/PUBLISHING.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PUBLISHING.md)
- [docs/Configuration.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/Configuration.md)
- [docs/PluginAssemblies.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PluginAssemblies.md)
- [docs/FactoryKeyConventions.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/FactoryKeyConventions.md)
- [docs/ROADMAP.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/ROADMAP.md)
- Per-pattern markdown under `DesignPatterns/docs/` (Chinese, maintainer-oriented)
11 changes: 9 additions & 2 deletions docs/samples.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,23 @@ The main [DesignPatterns](https://github.com/Skymly/DesignPatterns) CI checks ou
| **DesignPatterns.Samples.GenerateSingleton** | `[GenerateSingleton]` |
| **DesignPatterns.Samples.DependencyInjection** | `RegisterDi` for Strategy / Factory / Handler |
| **DesignPatterns.Samples.State** | Manual `TransitionTableBuilder` + `[StateMachine]` order lifecycle |
| **DesignPatterns.Samples.PluginAssemblies** | Multi-assembly `[RegisterStrategy]` + Autofac + `RegistryConfiguration` (`IConfiguration`) |

## NuGet consumption

Package **`Skymly.DesignPatterns` `0.2.3-preview1`** is on [nuget.org](https://www.nuget.org/packages/Skymly.DesignPatterns) (early preview). In the samples repo, switch off the sibling project reference:
Package **`Skymly.DesignPatterns` `0.2.3-preview2`** is on [nuget.org](https://www.nuget.org/packages/Skymly.DesignPatterns) (early preview). In the samples repo, switch off the sibling project reference:

```powershell
dotnet run --project DesignPatterns.Samples.Strategy -c Release -p:UseLocalDesignPatterns=false
```

Or set `UseLocalDesignPatterns` to `false` in `Directory.Build.props` / `Directory.Build.targets` when you only consume the published package.
`PluginAssemblies` also needs `Skymly.DesignPatterns.Extensions.Autofac` and `Skymly.DesignPatterns.Extensions.Configuration` (pinned with the meta package in samples `Directory.Build.props`).

```powershell
dotnet run --project DesignPatterns.Samples.PluginAssemblies/Host -c Release -p:UseLocalDesignPatterns=false
```

Or set `UseLocalDesignPatterns` to `false` in `Directory.Build.props` / `Directory.Build.targets` when you only consume published packages.

::: info Deprecated package ID
Do not use the old GitHub-only ID `DesignPatterns` (`0.1.0-preview1` / `preview2`). Use **`Skymly.DesignPatterns`** on nuget.org.
Expand Down
94 changes: 94 additions & 0 deletions docs/zh/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# 配置桥接

包:**`Skymly.DesignPatterns.Extensions.Configuration`**

将 **`IConfiguration`** 字符串映射到 **`IStrategyRegistry<string, TContract>`** 查找 — 适合宿主按配置键选择 strategy 实现,而不是手写 `switch`。

配合 `[RegisterStrategy]` 生成的 `{Contract}Registry` / `{Contract}Keys` 使用(见 [Strategy](./strategy.md))。

## 安装

不包含在 `Skymly.DesignPatterns` 元包中:

```powershell
dotnet add package Skymly.DesignPatterns.Extensions.Configuration --version 0.2.3-preview2
```

```xml
<PackageReference Include="Skymly.DesignPatterns.Extensions.Configuration" Version="0.2.3-preview2" />
```

目标框架:`netstandard2.0` 与 `net8.0`。依赖 `Microsoft.Extensions.Configuration.Abstractions`。

## API

```csharp
using DesignPatterns.Extensions.Configuration;
using Microsoft.Extensions.Configuration;

IConfiguration configuration = /* 宿主配置 */;

// 无法解析时抛出 RegistryConfigurationException。
var card = RegistryConfiguration.ResolveConfigured(
CardMotionRegistry.Instance,
configuration,
configurationKey: "Card",
defaultKey: CardMotionKeys.Alpha);

// 非抛出变体。
if (RegistryConfiguration.TryResolveConfigured(
CardMotionRegistry.Instance,
configuration,
"Card",
out var motion,
defaultKey: CardMotionKeys.Alpha))
{
// 使用 motion
}
```

### 解析顺序

1. 读取 `IConfiguration[configurationKey]`。
2. 值为缺失或空白时,若提供了 `defaultKey` 则使用它。
3. 调用 `registry.TryGet(strategyKey, out implementation)`。

`defaultKey` 优先使用 `{Contract}Keys` 常量,以便调用点保持 DP025 安全。

### 失败信息

`RegistryConfigurationException` 会包含配置键、配置值(或默认键)以及注册表 `Keys` 列表:

```text
Configuration key 'Card' has value 'beta' which is not registered. Registered keys: alpha, gamma.
```

## 宿主示例

```csharp
using DesignPatterns.Extensions.Configuration;
using Microsoft.Extensions.Configuration;

var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();

var card = RegistryConfiguration.ResolveConfigured(
CardMotionRegistry.Instance,
configuration,
"Card",
defaultKey: CardMotionKeys.Alpha);
```

## 遗留 App.config 宿主

**没有**单独的 `ConfigurationManager.AppSettings` 扩展包。请在宿主内把 AppSettings 适配为 `IConfiguration`(对 `RegistryConfiguration` 而言,索引器适配器即可),再调用同一 API。

最小适配器见 [PluginAssemblies 示例 Host](https://github.com/Skymly/DesignPatterns.Samples/tree/main/DesignPatterns.Samples.PluginAssemblies/Host);NuGet / sibling 消费方式见[示例](./samples.md)。

## 相关

- [Strategy](./strategy.md)
- [依赖注入](./dependency-injection.md)(Autofac / MSDI)
- [诊断](./diagnostics.md)(DP025、DP033)
- 维护者文档:[Configuration.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/Configuration.md)、[PluginAssemblies.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PluginAssemblies.md)
9 changes: 7 additions & 2 deletions docs/zh/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 依赖注入

包:**`DesignPatterns.Extensions.DependencyInjection`**
包:**`Skymly.DesignPatterns.Extensions.DependencyInjection`**

## 概述

Expand Down Expand Up @@ -28,4 +28,9 @@ PaymentStrategyRegistry.RegisterDi(services);

## 说明

核心元包 **`Skymly.DesignPatterns`** **不包含** DI 扩展;需要时请从主仓 sibling 引用 `DesignPatterns.Extensions.DependencyInjection`(独立 NuGet 包尚未发布)。
核心元包 **`Skymly.DesignPatterns`** **不包含** DI / Autofac 扩展。请从 nuget.org 单独安装:

- [`Skymly.DesignPatterns.Extensions.DependencyInjection`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.DependencyInjection)
- [`Skymly.DesignPatterns.Extensions.Autofac`](https://www.nuget.org/packages/Skymly.DesignPatterns.Extensions.Autofac)

Autofac 扩展提供与 `RegisterDi` 对称的 `RegisterAutofac(ContainerBuilder)` / `Create(ILifetimeScope)`。可与 MSDI 扩展并存;二者均不包含在元包中。
2 changes: 2 additions & 0 deletions docs/zh/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ IDE 帮助链接指向本页(`#dp###` 锚点)。

**修复:** 各供应商使用不同 key,或每个契约维度只引用一个供应商。单程序集内重复 key 仍由 **DP003**(生成器)报告。

见 [插件程序集示例](https://github.com/Skymly/DesignPatterns.Samples/tree/main/DesignPatterns.Samples.PluginAssemblies)、主仓 [PluginAssemblies.md](https://github.com/Skymly/DesignPatterns/blob/main/docs/PluginAssemblies.md),以及本站[配置桥接](./configuration.md)。

## State 转换表(DP026–DP031) {#state-转换表-dp026-dp031}

| ID | 级别 | 触发条件 |
Expand Down
Loading
Loading