# 依赖注入系统 **本文档引用的文件** - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs) - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs) - [README.md(IoC包)](file://GFramework.Core/ioc/README.md) - [IInitializable.cs](file://GFramework.Core.Abstractions/lifecycle/IInitializable.cs) - [IDisposable.cs](file://GFramework.Core.Abstractions/lifecycle/IDisposable.cs) - [ILifecycle.cs](file://GFramework.Core.Abstractions/lifecycle/ILifecycle.cs) - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs) - [IocContainerTests.cs](file://GFramework.Core.Tests/ioc/IocContainerTests.cs) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向GFramework的依赖注入系统,聚焦于IocContainer的实现与设计模式,系统阐述容器的注册与解析流程、生命周期管理机制(IInitializable、IDisposable)、类型安全与编译时检查、容器冻结与线程安全、最佳实践与故障排除,并给出可测试与可维护的架构建议。 ## 项目结构 IoC相关代码位于以下位置: - 核心实现:GFramework.Core/ioc/IocContainer.cs - 接口定义:GFramework.Core.Abstractions/ioc/IIocContainer.cs - 生命周期接口:GFramework.Core.Abstractions/lifecycle/IInitializable.cs、IDisposable.cs、ILifecycle.cs - 使用说明与示例:GFramework.Core/ioc/README.md - 架构集成:GFramework.Core/architecture/Architecture.cs - 单元测试:GFramework.Core.Tests/ioc/IocContainerTests.cs ```mermaid graph TB subgraph "抽象层" II["IIocContainer 接口"] LInit["IInitializable 接口"] LDispose["IDisposable 接口"] LLife["ILifecycle 接口"] end subgraph "实现层" IC["IocContainer 实现"] end subgraph "应用层" Arch["Architecture 架构"] Tests["IocContainerTests 测试"] end II --> IC LInit --> LLife LDispose --> LLife Arch --> IC Tests --> IC ``` 图表来源 - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L1-L116) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L1-L373) - [IInitializable.cs](file://GFramework.Core.Abstractions/lifecycle/IInitializable.cs#L1-L12) - [IDisposable.cs](file://GFramework.Core.Abstractions/lifecycle/IDisposable.cs#L1-L12) - [ILifecycle.cs](file://GFramework.Core.Abstractions/lifecycle/ILifecycle.cs#L1-L6) - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs#L1-L200) - [IocContainerTests.cs](file://GFramework.Core.Tests/ioc/IocContainerTests.cs#L1-L200) 章节来源 - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L1-L373) - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L1-L116) - [README.md(IoC包)](file://GFramework.Core/ioc/README.md#L1-L681) ## 核心组件 - IIocContainer:定义注册、解析、查询与容器管理的契约,涵盖单例、多实现、系统实例注册,以及Get/GetAll/GetRequired等解析方法。 - IocContainer:IIocContainer的具体实现,提供基于字典+集合的索引结构、读写锁的线程安全、容器冻结保护、日志记录与错误处理。 - 生命周期接口:IInitializable、IDisposable、ILifecycle,为组件提供初始化与销毁的标准能力,便于与容器生命周期协同。 章节来源 - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L1-L116) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L1-L373) - [IInitializable.cs](file://GFramework.Core.Abstractions/lifecycle/IInitializable.cs#L1-L12) - [IDisposable.cs](file://GFramework.Core.Abstractions/lifecycle/IDisposable.cs#L1-L12) - [ILifecycle.cs](file://GFramework.Core.Abstractions/lifecycle/ILifecycle.cs#L1-L6) ## 架构总览 IocContainer作为架构(Architecture)的核心组件之一,贯穿System/Model/Utility的注册与获取。容器采用“手动注册、类型安全、线程安全、容器冻结”的设计,避免自动解析带来的复杂度,强调可控的生命周期与清晰的依赖关系。 ```mermaid sequenceDiagram participant App as "应用代码" participant Arch as "Architecture" participant C as "IocContainer" participant S as "ISystem 实例" App->>Arch : "RegisterSystem(S)" Arch->>C : "Register(S)" C->>C : "写锁 + 注册内部索引" App->>Arch : "GetSystem()" Arch->>C : "Get()" C->>C : "读锁 + 查找类型索引" C-->>Arch : "返回实例或null" Arch-->>App : "返回实例" ``` 图表来源 - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs#L150-L175) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L166-L199) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L211-L230) ## 详细组件分析 ### IocContainer 实现与设计模式 - 设计模式:控制反转(IoC)与简单工厂结合,通过接口隔离与具体实现解耦。 - 数据结构: - _objects:HashSet,用于去重与快速判断实例是否存在。 - _typeIndex:Dictionary>,按类型索引实例集合,支持多实现。 - 并发控制:ReaderWriterLockSlim,读多写少场景下提升并发性能。 - 冻结机制:_frozen标志位,防止初始化后继续修改容器内容。 - 日志与错误:统一通过ILogger记录Debug/Info/Error,异常类型为InvalidOperationException。 ```mermaid classDiagram class IIocContainer { +RegisterSingleton(instance) +RegisterPlurality(instance) +RegisterSystem(system) +Register(instance) +Register(type, instance) +Get() +GetRequired() +GetAll() +GetAllSorted(comparison) +Contains() +ContainsInstance(instance) +Clear() +Freeze() } class IocContainer { -_lock : ReaderWriterLockSlim -_frozen : bool -_objects : HashSet -_typeIndex : Dictionary> -_logger : ILogger +RegisterSingleton(instance) +RegisterPlurality(instance) +RegisterSystem(system) +Register(instance) +Register(type, instance) +Get() +GetRequired() +GetAll() +GetAllSorted(comparison) +Contains() +ContainsInstance(instance) +Clear() +Freeze() } IIocContainer <|.. IocContainer ``` 图表来源 - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L1-L116) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L1-L373) 章节来源 - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L12-L373) - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L11-L116) ### 生命周期管理机制 - IInitializable:提供Init(),用于组件初始化。 - IDisposable:提供Destroy(),用于资源释放。 - ILifecycle:组合IInitializable与IDisposable,形成统一生命周期接口。 - 与容器的关系:容器本身不自动管理生命周期,但可通过注册实现ILifecycle的实例并在外部触发Init/Destroy,从而与容器管理的对象保持一致的生命周期节奏。 ```mermaid classDiagram class IInitializable { +Init() } class IDisposable { +Destroy() } class ILifecycle { } IInitializable <|-- ILifecycle IDisposable <|-- ILifecycle ``` 图表来源 - [IInitializable.cs](file://GFramework.Core.Abstractions/lifecycle/IInitializable.cs#L1-L12) - [IDisposable.cs](file://GFramework.Core.Abstractions/lifecycle/IDisposable.cs#L1-L12) - [ILifecycle.cs](file://GFramework.Core.Abstractions/lifecycle/ILifecycle.cs#L1-L6) 章节来源 - [IInitializable.cs](file://GFramework.Core.Abstractions/lifecycle/IInitializable.cs#L1-L12) - [IDisposable.cs](file://GFramework.Core.Abstractions/lifecycle/IDisposable.cs#L1-L12) - [ILifecycle.cs](file://GFramework.Core.Abstractions/lifecycle/ILifecycle.cs#L1-L6) ### 服务注册与解析流程 - 注册路径 - Register/Register(Type, object):写入内部索引,支持多实现。 - RegisterSingleton:检查类型是否已有实例,避免重复单例。 - RegisterPlurality:将实例同时注册到具体类型与其所有接口上。 - RegisterSystem:系统实例的便捷注册。 - 解析路径 - Get():返回首个实例或null。 - GetAll():返回全部实例列表。 - GetRequired():要求唯一实例,否则抛出异常。 - GetAllSorted:对实例进行排序后返回。 - 查询与工具 - Contains():检查类型是否已注册。 - ContainsInstance(object):检查具体实例是否在容器中。 - Clear():清空容器。 - Freeze():冻结容器,禁止后续修改。 ```mermaid flowchart TD Start(["开始"]) --> RegType{"注册类型?"} RegType --> |单例| CheckSingleton["检查类型是否已有实例"] CheckSingleton --> |有| Throw1["抛出异常"] CheckSingleton --> |无| AddSingleton["注册单例"] RegType --> |普通| AddNormal["注册到类型索引"] RegType --> |多实现| AddPlurality["注册到具体类型与所有接口"] AddSingleton --> End(["结束"]) AddNormal --> End AddPlurality --> End Throw1 --> End ``` 图表来源 - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L69-L98) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L166-L199) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L105-L123) 章节来源 - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L69-L199) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L211-L294) ### 类型安全与编译时检查 - 泛型约束:所有注册/解析均使用泛型,编译期类型检查,避免字符串键导致的错误。 - 接口契约:通过IIocContainer定义明确的API边界,IDE友好,支持智能提示与重构。 章节来源 - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L1-L116) - [README.md(IoC包)](file://GFramework.Core/ioc/README.md#L518-L523) ### 容器冻结与线程安全 - 冻结机制:Freeze()后禁止任何注册操作,防止运行时修改容器内容。 - 线程安全:读写锁保护注册/解析过程,读多写少场景下提升吞吐。 章节来源 - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L357-L370) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L21-L21) - [README.md(IoC包)](file://GFramework.Core/ioc/README.md#L524-L529) ### 与架构的集成 - Architecture持有IocContainer实例,封装RegisterSystem/GetSystem等常用方法,使注册与解析对上层透明。 - 通过RegisterSystem/Model/Utility等方法间接使用IocContainer,保证注册顺序与依赖关系可控。 章节来源 - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs#L154-L173) - [README.md(IoC包)](file://GFramework.Core/ioc/README.md#L147-L215) ## 依赖分析 - 组件耦合 - Architecture依赖IocContainer,实现注册与解析的高层封装。 - IocContainer依赖生命周期接口(IInitializable/IDisposable/ILifecycle),但不强制执行,仅作为类型约定。 - 外部依赖 - System.Threading.ReaderWriterLockSlim:提供高性能读写锁。 - ILogger/LoggerFactoryResolver:提供日志能力,便于调试与诊断。 ```mermaid graph LR Arch["Architecture"] --> IC["IocContainer"] IC --> II["IIocContainer 接口"] IC --> LIF["ILifecycle 接口族"] IC --> THR["ReaderWriterLockSlim"] IC --> LOG["ILogger/LoggerFactoryResolver"] ``` 图表来源 - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs#L154-L173) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L1-L373) - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L1-L116) - [ILifecycle.cs](file://GFramework.Core.Abstractions/lifecycle/ILifecycle.cs#L1-L6) 章节来源 - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs#L154-L173) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L1-L373) ## 性能考虑 - 结构选择:字典+集合的索引结构,平均O(1)的插入与查找,GetAll返回快照列表,避免并发修改导致的异常。 - 并发模型:读写锁在读多写少场景下显著提升性能;写锁粒度小,仅在注册阶段持有。 - 冻结策略:初始化完成后冻结容器,避免运行时注册带来的额外开销与不确定性。 - 建议 - 将高频解析的类型尽量注册为具体类型而非接口,减少接口查找成本。 - 控制注册数量与层级,避免过度注册导致索引膨胀。 - 使用GetRequired在关键路径上确保唯一性,减少分支判断。 [本节为通用性能指导,不直接分析具体文件] ## 故障排除指南 - “容器已冻结”异常 - 触发条件:在调用Freeze()之后再次尝试注册。 - 处理建议:将所有注册集中在初始化阶段完成,初始化结束后调用Freeze()。 - “重复单例注册”异常 - 触发条件:对同一类型多次调用RegisterSingleton()。 - 处理建议:确认单例注册逻辑,避免重复注册;或改用Register()注册多实现。 - “未找到实例”或“返回null” - 触发条件:Get()未匹配到实例。 - 处理建议:使用GetAll()确认是否注册;或改用GetRequired()在开发期暴露问题。 - “存在多个实例”异常 - 触发条件:GetRequired()匹配到多个实例。 - 处理建议:改为GetAll()获取列表,或调整注册策略确保唯一性。 - 线程安全相关问题 - 触发条件:在多线程环境下同时进行注册与解析。 - 处理建议:遵循容器自带的读写锁机制,不要在外部自行加锁;确保初始化阶段完成所有注册后再并发访问。 章节来源 - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L76-L98) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L240-L259) - [IocContainerTests.cs](file://GFramework.Core.Tests/ioc/IocContainerTests.cs#L1-L200) ## 结论 GFramework的IocContainer以简单、类型安全、线程安全与容器冻结为核心特性,适合需要明确生命周期与可控依赖关系的架构。通过与Architecture的集成,开发者可以在初始化阶段集中管理组件注册,运行时通过类型安全的API进行解析,配合ILifecycle接口实现统一的初始化与销毁流程。建议在实际项目中遵循初始化阶段注册、接口优先、避免运行时频繁注册、合理使用冻结与日志等最佳实践,以获得稳定、可测试且可维护的系统。 [本节为总结性内容,不直接分析具体文件] ## 附录 ### API参考(摘要) - 注册 - RegisterSingleton(T instance) - RegisterPlurality(object instance) - RegisterSystem(ISystem system) - Register(T instance) - Register(Type type, object instance) - 解析 - Get():返回首个实例或null - GetRequired():要求唯一实例,否则抛异常 - GetAll():返回全部实例 - GetAllSorted(Comparison):返回排序后的实例 - 查询与工具 - Contains():检查类型是否已注册 - ContainsInstance(object):检查具体实例是否在容器中 - Clear():清空容器 - Freeze():冻结容器,禁止后续修改 章节来源 - [IIocContainer.cs](file://GFramework.Core.Abstractions/ioc/IIocContainer.cs#L13-L116) - [IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs#L69-L370) ### 配置示例与使用要点 - 在架构初始化阶段集中注册System/Model/Utility。 - 使用接口类型注册,便于替换实现。 - 初始化完成后调用Freeze(),防止运行时修改。 - 使用GetRequired()在开发期暴露多实现或未注册问题。 章节来源 - [README.md(IoC包)](file://GFramework.Core/ioc/README.md#L577-L660) - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs#L154-L173)