Skip to content

Latest commit

 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IChingLibrary

一个使用现代 C# (.NET 10) 构建的易学库,提供周易六爻占卜的完整实现。

特性

  • 多语言国际化支持:内置中英文翻译,支持运行时切换语言,不影响系统其他本地化
  • 纯阳历转阴历转换:使用 lunar-csharp 库实现精确的历法转换
  • 京房纳甲法:标准纳甲法实现,为八卦卦爻绑定天干地支
  • 世应位置计算:根据八宫卦自动计算世爻和应爻位置
  • 六亲计算:根据五行生克关系计算六亲(父母、兄弟、妻财、官鬼、子孙)
  • 六神起法:根据日干自动起六神(青龙、朱雀、勾陈、螣蛇、白虎、玄武)
  • 神煞系统(Symbolic Stars):支持16 种神煞计算(贵人、禄神、文昌、驿马、桃花等),可基于源码扩展
  • 卦属特性:支持六冲卦、六合卦、游魂卦、归魂卦的识别
  • 灵活的构建器模式:可自定义占卜流程,选择需要的计算步骤
  • SOLID 设计原则:清晰的接口抽象,易于扩展和测试

项目结构

IChingLibrary/
├── src/
│   ├── IChingLibrary.Core/              # 核心抽象和基础类
│   │   ├── Abstractions/                 # 抽象接口
│   │   │   ├── IGenerative<T>            # 相生关系接口
│   │   │   ├── IRelationship<T>          # 通用关系接口
│   │   │   └── IRestrictive<T>           # 相克关系接口
│   │   ├── Annotations/                  # 注解
│   │   │   └── IChingElementEnumAttribute # 元素枚举特性
│   │   ├── Extensions/                   # 扩展方法
│   │   │   └── HexagramExtensions        # 卦扩展(获取辞文)
│   │   ├── Localization/                 # 国际化
│   │   │   ├── IChingTranslationManager  # 翻译管理器
│   │   │   ├── IIChingTranslationProvider # 翻译提供者接口
│   │   │   └── ResxTranslationProvider   # RESX 翻译提供者
│   │   ├── Resources/                    # 资源文件
│   │   │   └── IChingResources.*.resx    # 多语言资源
│   │   ├── IChingElement<T>              # 易学元素泛型基类
│   │   ├── YinYang                       # 阴阳
│   │   ├── FivePhase                     # 五行(金水木火土)
│   │   ├── FourSymbol                    # 四象(老阴、少阳、少阴、老阳)
│   │   ├── Trigram                       # 三爻卦(八卦)
│   │   ├── Hexagram                      # 六爻卦(六十四卦)
│   │   ├── StemBranch                    # 天干地支(干支)
│   │   └── GlobalUsings.cs               # 全局 using
│   │
│   ├── IChingLibrary.Generators/         # Roslyn 增量源代码生成器
│   │
│   └── IChingLibrary.SixLines/           # 六爻占卜实现
│       ├── Builder/                      # 起卦构建器与结构化步骤
│       │   ├── ICastingMethod            # 起卦方式接口
│       │   ├── IStructuringStep          # 结构化步骤接口
│       │   ├── SixLineDivinationBuilder  # 构建器
│       │   ├── DivinationContext         # 构建上下文
│       │   ├── DefaultCastingMethods     # 内置起卦方式
│       │   ├── NajiaStep                 # 纳甲步骤
│       │   ├── PositionStep              # 世应步骤
│       │   ├── SixKinStep                # 六亲步骤
│       │   ├── SixSpiritStep             # 六神步骤
│       │   ├── HiddenDeityStep           # 伏神步骤
│       │   └── SymbolicStarStep          # 神煞步骤
│       ├── Core/                         # 核心类型
│       │   ├── CastingTime               # 起卦时间
│       │   ├── HexagramNature            # 卦属特性(六冲、六合、游魂、归魂)
│       │   ├── LinePosition              # 爻位置(初爻到上爻)
│       │   ├── Position                  # 位置(世爻、应爻)
│       │   ├── SixKin                    # 六亲
│       │   ├── SixSpirit                 # 六神
│       │   ├── SymbolicStar              # 神煞类型
│       │   ├── SymbolicStarCollection    # 神煞集合
│       │   └── SixLineDivination         # 六爻占卜主类
│       ├── Extensions/                   # 扩展方法
│       │   ├── HexagramExtensions        # 卦扩展(卦属特性查询)
│       │   ├── HexagramInstanceExtensions # 卦实例扩展(卦身查找等)
│       │   └── LineExtensions            # 爻扩展(爻辞获取)
│       ├── HexagramInstance              # 卦实例
│       └── Line                          # 爻
└── test/                                 # 测试项目
    ├── IChingLibrary.Core.Test/          # 核心库测试
    └── IChingLibrary.SixLines.Test/      # 六爻库测试

快速开始

安装

# 克隆仓库
git clone https://github.com/TheodoreCheung/IChingLibrary.git
cd IChingLibrary

# 恢复 NuGet 包
dotnet restore

构建

# 构建整个解决方案
dotnet build IChingLibrary.slnx

# 构建特定项目
dotnet build src/IChingLibrary.SixLines/IChingLibrary.SixLines.csproj

使用示例

1. 时间起卦法(最简单)

根据年月日时自动起卦,无需手动指定四象:

using IChingLibrary.SixLines;

// 根据当前时间自动起卦
var divination = SixLineDivination.Create(DateTimeOffset.Now);

Console.WriteLine($"主卦:{divination.Original.Meta.Label}");
Console.WriteLine($"变卦:{divination.Changed?.Meta.Label ?? "无"}");

起卦逻辑:

  • 上卦 = (年地支值 + 阴历月份 + 阴历日) % 8
  • 下卦 = (年地支值 + 阴历月份 + 阴历日 + 时地支值) % 8
  • 动爻 = (年地支值 + 阴历月份 + 阴历日 + 时地支值) % 6

2. 随机数起卦法

使用随机数起卦:

// 指定上卦和下卦随机数(系统会自动计算动爻)
var divination1 = SixLineDivination.Create(
    DateTimeOffset.Now,
    upperTrigramNumber: 15,
    lowerTrigramNumber: 23
);

// 指定上卦、下卦和动爻随机数
var divination2 = SixLineDivination.Create(
    DateTimeOffset.Now,
    upperTrigramNumber: 15,
    lowerTrigramNumber: 23,
    changingLineNumber: 7
);

3. 指定主卦和变卦起卦

直接指定主卦和变卦:

using IChingLibrary.Core;

// 只指定主卦(无变卦)
var divination1 = SixLineDivination.Create(
    DateTimeOffset.Now,
    Hexagram.TheCreative  // 乾为天
);

// 指定主卦和变卦
var divination2 = SixLineDivination.Create(
    DateTimeOffset.Now,
    Hexagram.TheCreative,   // 主卦:乾为天
    Hexagram.TheReceptive   // 变卦:坤为地
);

// 使用卦值指定
var divination3 = SixLineDivination.Create(
    DateTimeOffset.Now,
    originalValue: 63,   // 乾为天(0b111111)
    changedValue: 0      // 坤为地(0b000000)
);

4. 使用四象数组(传统方式)

直接使用四象数组起卦:

using IChingLibrary.Core;
using IChingLibrary.SixLines;

// 使用 FourSymbol[] 数组(C# 12 集合表达式)
// 注意:数组顺序必须从初爻到上爻
var divination1 = SixLineDivination.Create(
    DateTimeOffset.Now,
    [
        FourSymbol.YoungYang, FourSymbol.YoungYang, FourSymbol.YoungYang,
        FourSymbol.YoungYang, FourSymbol.YoungYang, FourSymbol.YoungYang
    ]
);

// 使用 byte[] 数组(6=老阴,7=少阳,8=少阴,9=老阳)
// 注意:数组顺序必须从初爻到上爻
var divination2 = SixLineDivination.Create(
    DateTimeOffset.Now,
    [9, 8, 7, 6, 8, 7]  // 索引0=初爻, 索引5=上爻
);

// 访问结果
Console.WriteLine($"主卦:{divination2.Original.Meta.Label}");
Console.WriteLine($"变卦:{divination2.Changed?.Meta.Label ?? "无"}");

// 遍历爻信息
foreach (var line in divination2.Original.Lines)
{
    Console.WriteLine($"{line.LinePosition.Label}: {line.YinYang.Label}, " +
                      $"{line.StemBranch}, {line.SixKin.Label}, " +
                      $"{line.SixSpirit?.Label ?? "无"}, {line.Position?.Label ?? "无"}");
}

5. 自定义流程(构建器模式)

使用构建器自由选择起卦方式与结构化步骤:

using IChingLibrary.Core;
using IChingLibrary.SixLines;
using IChingLibrary.SixLines.Builder;

// 时间起卦 + 自定义步骤组合
var divination = SixLineDivination
    .CreateBuilder()
    .UseMethod(new TimeBasedCastingMethod(DateTimeOffset.Now))
    .WithStep(new NajiaStep())       // 纳甲
    .WithStep(new PositionStep())    // 世应位置
    .WithStep(new SixKinStep())      // 六亲
    // 不需要六神
    .Build();

// 随机数起卦 + 只纳甲,不需要其他步骤
var divination2 = SixLineDivination
    .CreateBuilder()
    .UseMethod(new NumberBasedCastingMethod(DateTimeOffset.Now, 15, 23))
    .WithStep(new NajiaStep())
    .Build();

// 直接指定四象值 + 默认流程
var divination3 = SixLineDivination
    .CreateBuilder()
    .UseMethod(new CoinCastingMethod(DateTimeOffset.Now,
    [
        FourSymbol.OldYang,  // 9
        FourSymbol.YoungYin, // 8
        FourSymbol.YoungYang,// 7
        FourSymbol.OldYin,   // 6
        FourSymbol.YoungYin, // 8
        FourSymbol.YoungYang // 7
    ]))
    .WithDefaultSteps()
    .Build();

// 直接指定卦象 + 默认流程
var divination4 = SixLineDivination
    .CreateBuilder()
    .UseMethod(new SpecifyingHexagramCastingMethod(DateTimeOffset.Now, Hexagram.TheCreative, Hexagram.TheReceptive))
    .WithDefaultSteps()
    .Build();

// 只创建卦实例,不执行任何计算步骤
var divination5 = SixLineDivination
    .CreateBuilder()
    .UseMethod(new CoinCastingMethod(DateTimeOffset.Now,
    [
        FourSymbol.YoungYang,
        FourSymbol.YoungYang,
        FourSymbol.YoungYang,
        FourSymbol.YoungYang,
        FourSymbol.YoungYang,
        FourSymbol.YoungYang
    ]))
    .Build();

如果只执行了部分结构化步骤,SixLineDivination.ToString() 现在会对尚未计算的字段输出 _ 占位符,而不是抛出异常。

在性能敏感的读取路径中,可以优先使用低分配访问接口,避免重复快照或异常式读取:

var emptyBranches = divination.CastingTime.StemBranch.Day.EmptyBranchesMemory;

if (divination.SymbolicStars?.TryGetStarsMemory(SymbolicStar.Nobleman, out var noblemanBranches) == true)
{
    Console.WriteLine(string.Join("、", noblemanBranches.ToArray()));
}

var line = divination.Original.Lines[0];
if (line.TryGetStemBranch(out var stemBranch) && line.TryGetSixKin(out var sixKin))
{
    Console.WriteLine($"{stemBranch} / {sixKin}");
}

6. 自定义结构化步骤

IStructuringStep 是结构化步骤扩展点,主要用于库内扩展。若需在外部程序集中访问占卜数据并实现自定义步骤,请基于源码进行扩展,或通过 InternalsVisibleTo 开放内部访问。

7. 自定义起卦方式

ICastingMethod 是起卦方式扩展点,默认用于库内实现。若需自定义起卦方式并返回 SixLineDivination,建议基于源码扩展或开放内部构造器访问。

8. 变卦处理

变卦(有变爻的卦)会自动计算。默认流程中,变卦仅进行纳甲与六亲计算,世应、六神、伏神与神煞仅对主卦计算:

// 老阳(9)和老阴(6)为变爻
var divination = SixLineDivination.Create(
    DateTimeOffset.Now,
    [FourSymbol.OldYang, FourSymbol.YoungYang, FourSymbol.YoungYang,
     FourSymbol.YoungYang, FourSymbol.YoungYang, FourSymbol.YoungYang]
);

if (divination.Changed != null)
{
    Console.WriteLine($"主卦:{divination.Original.Meta.Label}");
    Console.WriteLine($"变卦:{divination.Changed.Meta.Label}");

    foreach (var line in divination.Changed.Lines)
    {
        Console.WriteLine($"{line.LinePosition.Label}: {line.SixKin.Label}");
    }
}

9. 神煞系统(Symbolic Stars)

神煞系统(Symbolic Stars)

神煞系统提供 16 种预定义神煞的计算,支持自定义扩展:

using IChingLibrary.Core;
using IChingLibrary.SixLines;

// 默认流程已包含神煞计算
var divination = SixLineDivination.Create(DateTimeOffset.Now);

// 查询卦身
var hexagramBody = divination.Original.FindHexagramBody();
Console.WriteLine($"卦身:{hexagramBody?.Label ?? "无"}");

// 查询贵人(多值神煞)
var nobleman = divination.SymbolicStars?.GetStars(SymbolicStar.Nobleman);
Console.WriteLine($"贵人:{string.Join("、", nobleman?.Select(b => b.Label) ?? [])}");

// 查询禄神(单值神煞)
var salarySpirit = divination.SymbolicStars?.GetStars(SymbolicStar.SalarySpirit);
Console.WriteLine($"禄神:{salarySpirit?[0].Label ?? "无"}");

// 检查某个爻上的神煞(按地支查询)
var line = divination.Original.Lines[0];
var lineStars = divination.SymbolicStars?.GetStarsForBranch(line.StemBranch.Branch) ?? [];
Console.WriteLine($"{line.LinePosition.Label}神煞:{string.Join("、", lineStars.Select(s => s.Label))}");

// 检查某个地支上的所有神煞
var branch = EarthlyBranch.Zi;
var branchStars = divination.SymbolicStars?.GetStarsForBranch(branch) ?? [];
Console.WriteLine($"子神煞:{string.Join("、", branchStars.Select(s => s.Label))}");

自定义神煞

默认流程包含 SymbolicStarStep(内置 16 种神煞)。如需扩展神煞计算,请基于源码扩展结构化步骤,或通过 InternalsVisibleTo 开放内部访问后进行定制。

预定义神煞类型

中文名 英文名 计算依据
贵人 Nobleman 日干(甲戊→牛羊,乙己→鼠猴,丙丁→猪鸡,壬癸→兔蛇,庚辛→马虎)
禄神 SalarySpirit 日干(甲→寅,乙→卯,丙戊→巳,丁己→午,庚→申,辛→酉,壬→亥,癸→子)
文昌 CultureFlourish 日干(甲→巳,乙→午,丙戊→申,丁己→酉,庚→亥,辛→子,壬→寅,癸→卯)
驿马 PostHorse 日支(寅午戌→申,亥卯未→巳,巳酉丑→亥,申子辰→寅)
桃花 PeachBlossom 日支(寅午戌→卯,亥卯未→辰,巳酉丑→午,申子辰→酉)
羊刃 YangBlade 日干(甲→卯,乙→寅,丙戊→午,丁己→巳,庚→酉,辛→申,壬→子,癸→亥)
将星 GeneralsStar 日支(寅午戌→午,亥卯未→卯,巳酉丑→酉,申子辰→子)
华盖 Canopy 日支(寅午戌→戌,亥卯未→未,巳酉丑→丑,申子辰→辰)
谋星 StarOfStrategy 日支(寅午戌→辰,亥卯未→丑,巳酉丑→未,申子辰→戌)
灾煞 DisasterMalignity 日支(寅午戌→子,亥卯未→酉,巳酉丑→卯,申子辰→午)
劫煞 RobberyMalignity 日支(寅午戌→亥,亥卯未→申,巳酉丑→寅,申子辰→巳)
亡神 DeathSpirit 日支(寅午戌→巳,亥卯未→寅,巳酉丑→申,申子辰→亥)
天医 CelestialPhysician 月支(退一位)
天喜 HeavenlyJoy 月支(寅卯辰→戌,巳午未→丑,申酉戌→辰,亥子丑→未)
床帐 MarriageBed 卦身五行(火→辰戌丑未,金→寅卯,水→巳午,木→申酉,土→亥子)
香闺 BridalChamber 卦身五行(火→申酉,金→寅卯,水→巳午,木→辰戌丑未,土→亥子)

10. 卦属特性

支持识别卦的特殊属性(六冲、六合、游魂、归魂):

using IChingLibrary.Core;
using IChingLibrary.SixLines;

var divination = SixLineDivination.Create(DateTimeOffset.Now);
var hexagram = divination.Original.Meta;

// 获取卦属特性
var nature = hexagram.GetNature();
if (nature != null)
{
    Console.WriteLine($"卦属:{nature.Label}");
    // 输出可能是:六冲卦、六合卦、游魂卦、归魂卦
}
else
{
    Console.WriteLine("此卦无特殊卦属");
}

卦属特性说明

卦属 英文名 说明
六冲卦 SixClashes 纯卦(8个)+ 无妄、大壮,共10个
六合卦 SixHarmonies 否、泰、节、困、旅、贲、豫、复,共8个
游魂卦 WanderingSoul 各宫第7卦,共8个
归魂卦 ReturningSoul 各宫第8卦,共8个

11. 获取卦辞、彖辞、象辞

IChingLibrary 支持获取六十四卦的卦辞、彖辞、象辞(大象),以及每个爻的爻辞和小象辞。

11.1 基础用法

通过扩展方法获取卦的辞文:

using IChingLibrary.Core;
using IChingLibrary.SixLines;

// 创建卦实例
var qian = Hexagram.TheCreative;
var instance = new HexagramInstance(qian);

// 获取卦辞
string statement = qian.GetStatement();
Console.WriteLine($"卦辞:{statement}");
// 输出:卦辞:元,亨,利,贞。

// 获取彖辞
string commentary = qian.GetCommentary();
Console.WriteLine($"彖辞:{commentary}");
// 输出:彖辞:大哉乾元,万物资始...

// 获取象辞(大象)
string image = qian.GetImage();
Console.WriteLine($"象辞:{image}");
// 输出:象辞:天行健,君子以自强不息。

11.2 获取爻辞和小象辞

通过扩展方法获取爻的辞文:

using IChingLibrary.Core;
using IChingLibrary.SixLines;

var qian = Hexagram.TheCreative;
var instance = new HexagramInstance(qian);

// 遍历所有爻
foreach (var line in instance.Lines)
{
    // 获取爻辞
    string lineStatement = line.GetStatement(qian);

    // 获取小象辞
    string lineImage = line.GetImage(qian);

    Console.WriteLine($"{line.LinePosition.Label}爻:");
    Console.WriteLine($"  爻辞:{lineStatement}");
    Console.WriteLine($"  小象:{lineImage}");
}

// 输出示例:
// First爻:
//   爻辞:潜龙,勿用。
//   小象:潜龙勿用,阳在下也。
// Second爻:
//   爻辞:见龙在田,利见大人。
//   小象:见龙在田,德施普也。
// ...

11.3 指定文化参数

所有获取辞文的方法都支持指定文化参数:

using System.Globalization;
using IChingLibrary.Core;

var qian = Hexagram.TheCreative;
var zh = new CultureInfo("zh-Hans");
var en = new CultureInfo("en");

// 获取中文卦辞
string statementZh = qian.GetStatement(zh);
Console.WriteLine(statementZh);  // 输出:元,亨,利,贞。

// 获取英文卦辞
string statementEn = qian.GetStatement(en);
Console.WriteLine(statementEn);  // 输出:Sublime success, perseverance furthers.

// 获取中文爻辞
var instance = new HexagramInstance(qian);
var firstLine = instance.Lines[0];
string lineStatementZh = firstLine.GetStatement(qian, zh);
Console.WriteLine(lineStatementZh);  // 输出:潜龙,勿用。

// 获取英文爻辞
string lineStatementEn = firstLine.GetStatement(qian, en);
Console.WriteLine(lineStatementEn);  // 输出:Hidden dragon. Do not act.

11.4 扩展方法列表

HexagramExtensions (位于 IChingLibrary.Core.Extensions):

方法 说明 返回类型
GetStatement(CultureInfo? culture = null) 获取卦辞 string
GetCommentary(CultureInfo? culture = null) 获取彖辞 string
GetImage(CultureInfo? culture = null) 获取象辞(大象) string

HexagramExtensions (位于 IChingLibrary.SixLines.Extensions):

方法 说明 返回类型
GetNature(this Hexagram hexagram) 获取卦属特性 HexagramNature?

LineExtensions (位于 IChingLibrary.SixLines.Extensions):

方法 说明 返回类型
GetStatement(Hexagram hexagram, CultureInfo? culture = null) 获取爻辞 string
GetImage(Hexagram hexagram, CultureInfo? culture = null) 获取小象辞 string

11.5 完整示例

using System.Globalization;
using IChingLibrary.Core;
using IChingLibrary.Core.Localization;
using IChingLibrary.SixLines;

// 设置默认语言
IChingTranslationManager.DefaultCulture = new CultureInfo("zh-Hans");

// 创建占卜
var divination = SixLineDivination.Create(DateTimeOffset.Now);
var hexagram = divination.Original.Meta;

// 显示卦信息
Console.WriteLine($"卦名:{hexagram.Label}");
Console.WriteLine($"卦辞:{hexagram.GetStatement()}");
Console.WriteLine($"彖辞:{hexagram.GetCommentary()}");
Console.WriteLine($"象辞:{hexagram.GetImage()}");

// 显示卦属特性
var nature = hexagram.GetNature();
if (nature != null)
{
    Console.WriteLine($"卦属:{nature.Label}");
}
Console.WriteLine();

// 显示每个爻的信息
foreach (var line in divination.Original.Lines)
{
    Console.WriteLine($"{line.LinePosition.Label}爻 ({line.YinYang.Label}):");
    Console.WriteLine($"  爻辞:{line.GetStatement(hexagram)}");
    Console.WriteLine($"  小象:{line.GetImage(hexagram)}");
    Console.WriteLine($"  六亲:{line.SixKin?.Label ?? "未计算"}");
    Console.WriteLine($"  世应:{line.Position?.Label ?? "无"}");
    Console.WriteLine();
}

12. 多语言国际化支持

IChingLibrary 内置了完整的多语言支持,默认提供简体中文和英文两种语言。所有易学元素(YinYang、FivePhase、Trigram、Hexagram、HeavenlyStem、EarthlyBranch 等)都支持本地化显示。

12.1 基础用法

所有易学元素都提供了 ToString() 方法,会根据当前文化设置返回对应的翻译:

using System.Globalization;
using IChingLibrary.Core;
using IChingLibrary.Core.Localization;

// 设置易学库默认语言为简体中文
IChingTranslationManager.DefaultCulture = new CultureInfo("zh-Hans");

Console.WriteLine(YinYang.Yin);      // 输出:阴
Console.WriteLine(YinYang.Yang);     // 输出:阳
Console.WriteLine(FivePhase.Metal);  // 输出:金
Console.WriteLine(Trigram.Qian);     // 输出:乾
Console.WriteLine(Hexagram.TheCreative);  // 输出:乾为天

// 切换为英文
IChingTranslationManager.DefaultCulture = new CultureInfo("en");

Console.WriteLine(YinYang.Yin);      // 输出:Yin
Console.WriteLine(YinYang.Yang);     // 输出:Yang
Console.WriteLine(FivePhase.Metal);  // 输出:Metal
Console.WriteLine(Trigram.Qian);     // 输出:Qian
Console.WriteLine(Hexagram.TheCreative);  // 输出:The Creative

12.2 干支组合翻译

StemBranch 类也会根据文化设置返回正确的翻译:

// 中文环境
IChingTranslationManager.DefaultCulture = new CultureInfo("zh-Hans");
var stemBranch = new StemBranch(HeavenlyStem.Jia, EarthlyBranch.Zi);
Console.WriteLine(stemBranch);  // 输出:甲子

// 英文环境
IChingTranslationManager.DefaultCulture = new CultureInfo("en");
Console.WriteLine(stemBranch);  // 输出:JiaZi

12.3 指定文化参数

如果不想使用全局的 DefaultCulture,可以为每个 ToString() 调用指定文化参数:

var zh = new CultureInfo("zh-Hans");
var en = new CultureInfo("en");

// 即使 DefaultCulture 是英文,也可以指定使用中文
IChingTranslationManager.DefaultCulture = new CultureInfo("en");

Console.WriteLine(YinYang.Yin.ToString(zh));  // 输出:阴
Console.WriteLine(YinYang.Yin.ToString(en));  // 输出:Yin

12.4 应用启动时设置语言

在应用程序启动时设置易学库的默认语言:

// ASP.NET Core 应用 - Program.cs
var builder = WebApplication.CreateBuilder(args);

// 根据用户配置或请求首选项设置易学库语言
var userLanguage = builder.Configuration["AppSettings:Language"] ?? "zh-Hans";
IChingTranslationManager.DefaultCulture = new CultureInfo(userLanguage);

var app = builder.Build();
app.Run();
// WPF/WinForms 应用 - App.xaml.cs 或 Program.cs
public static class Program
{
    [STAThread]
    public static void Main()
    {
        // 从用户设置读取语言偏好
        var language = UserService.GetUserLanguagePreference();
        IChingTranslationManager.DefaultCulture = new CultureInfo(language);

        // 启动应用程序
        var app = new MainWindow();
        app.ShowDialog();
    }
}

12.5 运行时切换语言

支持在应用程序运行时动态切换语言,不影响系统其他本地化设置:

// 用户在应用设置中选择语言
public void ChangeLanguage(string languageCode)
{
    IChingTranslationManager.DefaultCulture = new CultureInfo(languageCode);

    // 重新加载界面或刷新显示
    RefreshDisplay();
}

// 示例:切换为简体中文
ChangeLanguage("zh-Hans");

// 示例:切换为英文
ChangeLanguage("en");

12.5.1 并发场景下的局部语言作用域

如果你在 ASP.NET、后台任务或并发异步流程中需要为单个执行流临时覆盖语言或翻译提供者,建议使用 BeginScope(),避免直接修改全局静态状态:

using System.Globalization;
using IChingLibrary.Core;
using IChingLibrary.Core.Localization;

async Task<string> RenderAsync(string language)
{
    using var _ = IChingTranslationManager.BeginScope(culture: new CultureInfo(language));
    await Task.Delay(10);
    return YinYang.Yin.ToString();
}

BeginScope() 只影响当前异步流;释放作用域后会自动恢复到之前的设置。

12.6 文化解析优先级

当获取翻译时,系统按以下优先级解析文化:

1. 显式指定的 CultureInfo 参数(最高优先级)
   ↓
2. IChingTranslationManager.DefaultCulture(如果已设置)
   ↓
3. CultureInfo.CurrentUICulture(系统 UI 文化,默认回退)
// 示例:优先级演示
IChingTranslationManager.DefaultCulture = new CultureInfo("zh-Hans");
// 假设系统 CurrentUICulture 是 "en"

var element = YinYang.Yin;

// 1. 最高优先级:显式指定
element.ToString(new CultureInfo("en"));  // 输出:Yin

// 2. 次优先级:DefaultCulture
element.ToString();  // 输出:阴

// 3. 默认回退:CurrentUICulture(当 DefaultCulture 为 null 时)
IChingTranslationManager.DefaultCulture = null;
element.ToString();  // 输出:Yin

12.7 自定义翻译提供者

如果需要支持更多语言或自定义翻译,可以实现 IIChingTranslationProvider 接口:

using System.Globalization;
using IChingLibrary.Core.Localization;

// 自定义翻译提供者
public class JsonTranslationProvider : IIChingTranslationProvider
{
    private readonly Dictionary<string, Dictionary<string, string>> _translations;

    public JsonTranslationProvider(string jsonFilePath)
    {
        // 从 JSON 文件加载翻译
        var json = File.ReadAllText(jsonFilePath);
        _translations = JsonSerializer.Deserialize<
            Dictionary<string, Dictionary<string, string>>>(json)!;
    }

    public string? GetTranslation(string typeName, string label, CultureInfo culture)
    {
        var key = $"{typeName}.{label}";
        var cultureName = culture.Name;

        if (_translations.TryGetValue(cultureName, out var langDict))
        {
            return langDict.GetValueOrDefault(key);
        }

        return null;  // 找不到翻译时返回 null,将使用 Label
    }
}

// 使用自定义提供者
IChingTranslationManager.Provider = new JsonTranslationProvider("translations.json");
// 数据库翻译提供者示例
public class DatabaseTranslationProvider : IIChingTranslationProvider
{
    private readonly IDbConnection _dbConnection;

    public DatabaseTranslationProvider(IDbConnection dbConnection)
    {
        _dbConnection = dbConnection;
    }

    public string? GetTranslation(string typeName, string label, CultureInfo culture)
    {
        const string sql = @"
            SELECT TranslationText
            FROM Translations
            WHERE TypeName = @TypeName
              AND Label = @Label
              AND CultureName = @CultureName";

        return _dbConnection.QuerySingleOrDefault<string>(sql, new
        {
            TypeName = typeName,
            Label = label,
            CultureName = culture.Name
        });
    }
}

// 使用数据库提供者
IChingTranslationManager.Provider = new DatabaseTranslationProvider(dbConnection);

12.8 重置为默认设置

如果需要恢复到默认的 RESX 翻译提供者和文化设置:

// 重置所有自定义设置
IChingTranslationManager.ResetToDefault();

// 之后将使用:
// - Provider: 默认的 ResxTranslationProvider
// - DefaultCulture: null(使用系统 CurrentUICulture)

12.9 与系统本地化的隔离

IChingTranslationManager.DefaultCulture 只影响易学库的翻译,不会影响应用程序的其他本地化(如日期、货币格式等):

// 设置系统 UI 文化为英语
CultureInfo.CurrentUICulture = new CultureInfo("en");

// 设置易学库语言为简体中文
IChingTranslationManager.DefaultCulture = new CultureInfo("zh-Hans");

// 易学元素显示中文
Console.WriteLine(YinYang.Yin);  // 输出:阴

// 其他本地化仍然使用系统语言
var date = DateTime.Now;
Console.WriteLine(date.ToString("d"));  // 输出:M/D/YYYY(英语格式)

12.10 支持的语言

目前内置支持的语言:

语言名称 语言代码 说明
English en 默认语言(回退语言)
简体中文 zh-Hans 简体中文翻译

如需添加其他语言,可以:

  1. 创建新的 RESX 文件(如 IChingResources.ja.resx 用于日语)
  2. 或实现自定义 IIChingTranslationProvider

12.11 唯一键(UniqueKey)

每个易学元素都有 UniqueKey 属性,格式为 {TypeName}.{Label},用于资源查找和调试:

Console.WriteLine(YinYang.Yin.UniqueKey);      // 输出:YinYang.Yin
Console.WriteLine(FivePhase.Metal.UniqueKey);  // 输出:FivePhase.Metal
Console.WriteLine(Trigram.Qian.UniqueKey);     // 输出:Trigram.Qian
Console.WriteLine(Hexagram.TheCreative.UniqueKey);  // 输出:Hexagram.TheCreative

API 参考

SixLineDivination

主类,提供静态方法创建占卜实例。

Create 方法(起卦)

方法 说明
Create(DateTimeOffset) 时间起卦法,根据年月日时自动起卦
Create(DateTimeOffset, int, int, int?) 随机数起卦法(上卦数、下卦数、动爻数可选)
Create(DateTimeOffset, Hexagram, Hexagram?) 指定主卦和变卦起卦
Create(DateTimeOffset, byte, byte?) 指定主卦值和变卦值起卦
Create(DateTimeOffset, FourSymbol[]) 使用四象数组起卦(数组顺序:从初爻到上爻)
Create(DateTimeOffset, byte[]) 使用四象值数组起卦(数组顺序:从初爻到上爻)

CreateBuilder 方法(自定义流程)

方法 说明
CreateBuilder() 创建构建器

属性

属性 类型 说明
CastingTime CastingTime 起卦时间
Original HexagramInstance 主卦
Changed HexagramInstance? 变卦(如有)
SymbolicStars SymbolicStarCollection? 神煞集合

SixLineDivinationBuilder

构建器类,用于自定义占卜流程。ICastingMethod 与 IStructuringStep 为扩展点,默认主要用于库内实现。

起卦方式(必须指定)

方法 说明
UseMethod(ICastingMethod) 指定起卦方式

流程配置方法

方法 说明
WithDefaultSteps() 添加默认完整流程(纳甲、世应、六亲、六神、伏神、神煞)
WithStep(IStructuringStep) 添加自定义结构化步骤
Build() 构建占卜实例

ICastingMethod

起卦方式接口。

public interface ICastingMethod
{
    SixLineDivination Cast();
}

IStructuringStep

结构化步骤接口。

public interface IStructuringStep
{
    IEnumerable<Type> RequiredSteps { get; }
    void Execute(DivinationContext context);
}

DivinationContext

构建器上下文,用于在步骤中访问与写入占卜数据(属性为内部可见)。

属性 类型 说明
SixLineDivination SixLineDivination 占卜数据容器(主卦、变卦、起卦时间、神煞等,内部可见)

IChingTranslationManager

易学翻译管理器,提供多语言支持的核心 API。

属性

属性 类型 说明
Provider IIChingTranslationProvider 获取或设置当前翻译提供者
DefaultCulture CultureInfo? 获取或设置易学库的默认文化

方法

方法 说明
GetTranslation(string typeName, string label, CultureInfo? culture = null) 获取指定元素的翻译文本
ResetToDefault() 重置为默认翻译提供者和文化设置

使用示例

using IChingLibrary.Core.Localization;

// 设置默认语言
IChingTranslationManager.DefaultCulture = new CultureInfo("zh-Hans");

// 获取翻译
var translation = IChingTranslationManager.GetTranslation("YinYang", "Yin");
Console.WriteLine(translation);  // 输出:阴

// 使用自定义提供者
IChingTranslationManager.Provider = new MyCustomProvider();

// 重置为默认设置
IChingTranslationManager.ResetToDefault();

IIChingTranslationProvider

翻译提供者接口,用于实现自定义翻译逻辑。

方法

方法 返回类型 说明
GetTranslation(string typeName, string label, CultureInfo culture) string? 获取指定元素和文化的翻译,找不到时返回 null

IChingElement

所有易学元素的抽象基类,提供多语言支持的通用功能。

属性

属性 类型 说明
Value byte 元素的唯一标识值
Label string 元素的标签名称
UniqueKey string 元素的唯一键,格式为 {TypeName}.{Label}

方法

方法 返回类型 说明
ToString() string 返回元素的翻译文本(使用 DefaultCulture 或 CurrentUICulture)
ToString(CultureInfo culture) string 返回指定文化的翻译文本

文化解析优先级

1. ToString(CultureInfo culture) 中的 culture 参数(最高优先级)
   ↓
2. IChingTranslationManager.DefaultCulture(如果已设置)
   ↓
3. CultureInfo.CurrentUICulture(系统 UI 文化,默认回退)

构建流程

默认完整流程包含以下步骤:

1. 指定起卦方式(ICastingMethod)
   ├── TimeBasedCastingMethod
   ├── NumberBasedCastingMethod
   ├── CoinCastingMethod
   └── SpecifyingHexagramCastingMethod
   ↓
2. 执行 Cast() 生成种子数据(CastingTime + 主卦/变卦)
   ↓
3. 创建 DivinationContext
   ↓
4. 结构化步骤拓扑排序(基于 RequiredSteps 依赖)
   ↓
5. 依次执行步骤
   ├── NajiaStep
   ├── PositionStep
   ├── SixKinStep
   ├── SixSpiritStep
   ├── HiddenDeityStep
   └── SymbolicStarStep
   ↓
6. 返回占卜实例

设计原则

本项目遵循以下设计原则:

SOLID 原则

  • 单一职责原则(SRP):每个类只负责一个功能

    • ICastingMethod 实现:负责起卦与生成种子数据
    • SixLineDivinationBuilder:负责步骤配置、排序与构建
    • IStructuringStep 实现:负责单一结构化计算
    • SixLineDivination:统一 API 入口
  • 开闭原则(OCP):通过接口扩展,无需修改现有代码

    • 添加新起卦方式:实现 ICastingMethod
    • 添加新结构化步骤:实现 IStructuringStep
  • 里氏替换原则(LSP):不同起卦方式与步骤实现可互相替换

  • 接口隔离原则(ISP):接口职责明确,不强迫实现不需要的方法

  • 依赖倒置原则(DIP):依赖抽象接口而非具体实现

架构设计

┌─────────────────────────────────────────────────────────────────┐
│                     SixLineDivination                           │
│  - 统一的 API 入口                                               │
│  - 提供 Create(...) 与 CreateBuilder()                          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                   SixLineDivinationBuilder                       │
│  - UseMethod(ICastingMethod)                                     │
│  - WithDefaultSteps()/WithStep(...)                               │
│  - Build()                                                       │
└─────────────────────────────────────────────────────────────────┘
                              │
          ┌───────────────────┴───────────────────┐
          ▼                                       ▼
┌──────────────────────────────┐   ┌──────────────────────────────┐
│      ICastingMethod           │   │      IStructuringStep        │
│  - TimeBased/Number/Coin/...  │   │  - RequiredSteps              │
│  - Cast() 生成种子数据          │   │  - Execute(DivinationContext) │
└──────────────────────────────┘   └──────────────────────────────┘
                              │
                              ▼
                    ┌──────────────────────────┐
                    │     DivinationContext     │
                    │  - SixLineDivination      │
                    └──────────────────────────┘

技术栈

  • 目标框架: .NET 10.0
  • 语言版本: C# 12.0
  • 外部依赖: lunar-csharp(阴历转换)
  • 代码生成器: Microsoft.CodeAnalysis.CSharp

贡献

欢迎提交 Issue 和 Pull Request!

许可证

MIT License

致谢

About

A modern C#/.NET library for I Ching divination, with complete six-line reading support and core metaphysics primitives.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages