尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Extenject四种注入方式全解析:构造函数、字段、属性与方法注入实战教程

Extenject四种注入方式全解析:构造函数、字段、属性与方法注入实战教程 Extenject四种注入方式全解析构造函数、字段、属性与方法注入实战教程【免费下载链接】ExtenjectDependency Injection Framework for Unity Game Engine项目地址: https://gitcode.com/gh_mirrors/ex/Extenject如果你正在学习Unity 依赖注入那么 ExtenjectZenject 的活跃维护分支绝对是绕不开的框架。它被大量商业游戏项目采用能把你的代码从new 来 new 去的耦合泥潭中解放出来。而理解Extenject 注入方式就是掌握这个框架的第一课。本文将用最通俗的语言为你完整解析构造函数注入、字段注入、属性注入与方法注入这四种方式从原理、写法到选型建议一次讲透帮助你快速上手 Unity 依赖注入实战。上图是一个典型的 Extenject 项目场景SceneContext 作为全局容器Ship 及其子组件Cube、HealthHandler通过依赖注入实现解耦。为什么需要依赖注入先搞懂核心概念在传统 Unity 开发中对象之间的依赖关系通常是写死的HealthHandler需要Player就直接new一个或者到处找FindObjectOfType。这会导致两个问题耦合严重改一个类的构造所有引用它的地方都要跟着改难以测试无法在单元测试中替换掉真实依赖Extenject 的思路是把创建对象和使用对象分开。你只需要在 Installer 中声明谁依赖谁绑定框架会自动在合适的时机把依赖塞进你的类里——这个过程就叫注入。public class GameInstaller : MonoInstaller { public override void InstallBindings() { // 声明绑定凡是需要 IHealthHandler 的地方都注入 HealthHandler 实例 Container.BindIHealthHandler().ToHealthHandler().AsSingle(); } }之后任何类需要IHealthHandler都无需自己创建Extenject 会自动完成注入。下面进入正题看看它究竟是怎么塞进来的。第一种注入方式构造函数注入最推荐构造函数注入是指通过类的构造函数来接收依赖这也是官方文档中最推崇的方式。它的原理很简单Extenject 在实例化对象时会通过反射找出构造函数的参数列表从容器中逐个解析并传入。public class Ship { readonly IHealthHandler _healthHandler; // 构造函数参数由 Extenject 自动解析注入 public Ship(IHealthHandler healthHandler) { _healthHandler healthHandler; } }优点速览优势说明✅ 依赖明确一眼就能看出这个类需要什么✅ 不可变依赖用readonly修饰初始化后不可更改✅ 无循环依赖构造函数注入天然避免 A↔B 相互引用的死循环✅ 便于测试测试时直接new Ship(mock)即可小提示如果你写了多个构造函数需要给其中一个加上[Inject]特性告诉 Extenject用这个如果不加框架会默认选择参数最少的那一个该逻辑定义在反射注入核心 InjectTypeInfo.cs 中。第二种注入方式字段注入最省事字段注入是在构造函数执行完毕后立刻进行的所有标记了[Inject]特性的字段都会被 Extenject 从容器中查找并赋值。最方便的地方在于——字段可以是 private 的照样能注入。public class Ship { // 私有字段也能被注入无需任何 getter/setter [Inject] IHealthHandler _healthHandler; }字段注入的写法最简洁但要注意它的代价依赖不是readonly的对象在创建后依赖可能被悄悄换掉且无法像构造函数那样在声明阶段就约束依赖。适合快速原型和 MonoBehaviour 组件长期维护的项目建议谨慎使用。第三种注入方式属性注入与字段注入齐名属性注入和字段注入几乎一样只是作用对象从字段变成了 C# 属性。它的 setter 同样可以是私有的这样既保持了封装性又能让框架完成赋值。public class Ship { [Inject] public IHealthHandler HealthHandler { get; private set; } }属性注入在 Unity 中还有个特殊用途配合 Inspector 显示。如果你希望某个注入的依赖能在编辑器的 Inspector 面板中看到比如调试用属性注入比字段注入更灵活。不过从性能角度看字段注入略占优势属性注入在 IL2CPP / 反射烘焙场景下会多一些开销。第四种注入方式方法注入MonoBehaviour 的救星方法注入是四种方式中最特别的一个把[Inject]标记在方法上Extenject 会在所有字段/属性注入完成之后调用该方法并把方法参数从容器中解析注入。public class Ship : MonoBehaviour { [Inject] public void Init(IHealthHandler healthHandler, GameSettings settings) { // 在这里完成初始化逻辑 _healthHandler healthHandler; } }为什么 MonoBehaviour 必须用它因为 MonoBehaviour 的实例由 Unity 引擎创建不能有自定义构造函数。方法注入就成了给 MonoBehaviour 传递依赖的唯一正道。官方文档README.md 的Inject Methods章节也明确建议MonoBehaviour 一律使用方法注入。方法注入还有两个贴心特性可以有多个注入方法执行顺序是从基类到派生类类似构造函数的执行逻辑空参数列表也可以相当于初始化钩子——在所有注入完成后再执行初始化代码四种注入方式怎么选实战选型指南简单总结成一张速查表方便你随时查阅注入方式适用场景依赖可见性循环依赖推荐度构造函数注入普通 C# 类、核心业务逻辑⭐⭐⭐ 极高不支持好 首选方法注入MonoBehaviour、需要初始化逻辑⭐⭐⭐ 高支持 次选属性注入需要暴露给外部/Inspector 的依赖⭐⭐ 中支持 按需字段注入快速原型、组件内部依赖⭐ 低支持⚠️ 谨慎黄金法则能用构造函数注入就别用字段/属性注入遇到 MonoBehaviour 就上方法注入。这样写出来的代码依赖一目了然、可测试性最强。进阶技巧让注入更智能的 3 个小特性掌握了四种注入方式再学三个高频扩展特性你的 Extenject 水平就超过大多数新人了 标识注入Id同类型依赖多个实例时用[Inject(Id Player)]精确指定注入哪一个 可选注入InjectOptional依赖不存在时注入 null 而不是报错定义在 InjectOptionalAttribute.cs常用于默认值场景 局部注入InjectLocal只从当前 GameObject 所在的子容器查找依赖定义在 InjectLocalAttribute.cs适合多场景隔离// 示例可选注入 标识注入的组合用法 public class LevelHandler { [Inject(Id LevelConfig)] [InjectOptional] LevelConfig _config; // 找不到也不报错自动为 null }这些特性的底层实现都离不开 Extenject 强大的反射与类型信息解析系统感兴趣的话可以研究 InjectTypeInfo.cs 中InjectConstructor、InjectMethods、InjectMembers的分工以及 InjectUtil.cs 提供的参数解析工具。写在最后到这里Extenject 的构造函数注入、字段注入、属性注入与方法注入就全部讲完了。记住核心心法️ 普通类 →构造函数注入 MonoBehaviour →方法注入 想要灵活/快速 → 字段、属性注入按需使用把这四种注入方式练熟再配合 Installer 的绑定语法参考 CheatSheet.md 速查表你就能把 Unity 项目改造成高内聚、低耦合、易于测试的架构了。赶紧打开你的项目用依赖注入重构一个类试试吧【免费下载链接】ExtenjectDependency Injection Framework for Unity Game Engine项目地址: https://gitcode.com/gh_mirrors/ex/Extenject创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表