Init(args):Unity中的依赖注入神器!
Init(args)是一款专为Unity打造的依赖注入框架,从头开始设计,旨在与您熟悉的传统Unity工作流程无缝融合。

什么是Init(args)?

Init(args)是一个Unity的依赖注入框架,其关键目标是确保所有工具的各个方面与本地编辑器体验无缝融合。

Init(args)解决了哪些问题?

Unity编辑器的场景化工作流程是一个强大的工具,通过在Inspector中拖放引用到字段,已经为对象注入依赖提供了一个良好的基础。因此,Init(args)的目标不是在此方面重新造轮子,而是修复其中的各种不足,释放其全部潜力。
在原始Unity中,所有组件都需要自己找到所依赖对象的引用。其中一种方法是添加序列化字段,让用户可以使用Inspector来分配引用。虽然这样做很方便,但也存在一些限制,不能在每种情况下使用:
– 不能将对象分配给接口字段
– 不能跨场景或预制件分配对象
– 反复将相同的管理器拖放到组件中很繁琐
– 要切换管理器到不同的管理器,必须手动更新所有组件的引用
– 不能分配动态值,使得处理本地化文本、可寻址资源和随机化值等更困难
由于这些限制,组件通常不得不将序列化字段与其他解决依赖的方法相结合:单例、GetComponent、GetComponentInChildren、FindObjectOfType、FindWithTag、静态方法等等。这种混合使用的方式也带来了自己的问题:
– 可能会在组件的代码中增加很多不必要的噪音
– 依赖可能隐藏在代码的任何地方
– 依赖通常是硬编码到特定类中
– 依赖是使用硬编码的搜索方法定位的
即使通过这些方法组合成一个相对体面的组件,也很可能几乎不可能为其编写任何单元测试!
Init(args)可以为您解决所有这些问题。

保持简单

使用Init(args),您不必花费大量时间学习复杂的概念,比如绑定、容器、装饰器或上下文……实际上,您可以仅使用Inspector来满足大部分的依赖注入需求!不过,现在的灵活性更强。
当您想要在代码中初始化对象时,您仍然可以使用您已经熟悉的所有命令,比如AddComponent和Instantiate——只是现在您可以传入一些参数。
这个小而重要的变化意味着,您的组件不再是封闭的孤岛,也不再是隐藏依赖关系的黑匣子;当您用其依赖项实例化一个组件时,您可以确信它将正常工作。这也意味着为组件编写单元测试变得轻松愉快,甚至让您兴奋不已!

纯净的依赖注入

Init(args)的主要重点是在场景对象和预制件中,以及在代码中实现纯净的依赖注入。这意味着尽可能地少使用反射,而是使用泛型方法和接口来提供强类型的依赖传递路径。
这种方法有很多好处,比如与基于反射的解决方案相比具有更高的性能,并且在编译时尽早捕获用户错误。这种快速失败的设计在编辑器方面也有所体现,在编辑模式下会向控制台记录有关场景中缺少参数的警告。
纯净的依赖注入还有助于提高项目的可读性;对象之间的依赖关系不会被混淆,您可以轻松地在IDE和编辑器中跟踪依赖的轨迹——这在调试应用程序时至关重要。
点缀一些魔法的力量…除了提供所有Unity中纯净的依赖注入工具外,Init(args)还提供了一个强大的系统,可以像魔法一样创建共享实例,并自动将它们传递给客户端(或者,如果您愿意,限制在特定场景或转换层次结构中)。
这些共享实例被称为“服务”,您可以通过为任何类添加[Service]属性来创建一个新的服务。您可以将服务视为增强版的单例。
更容易创建(只需添加一个属性)。
自动传递给所有客户端组件。
服务可以轻松使用其他服务(无需执行顺序问题)。
当需要时,可以为个别组件覆盖服务参数。
支持从Addressables、Resources文件夹和场景加载服务。
在单元测试期间,服务可以替换为模拟对象。
服务系统使用了反射,但仅在初始化时使用,之后访问缓存的服务非常快速。

Inspector特性:

完全支持接口——直观的拖放和下拉式Inspector界面。
值提供程序——动态参数,例如随机值或运行时对象的引用。
Null参数保护——在编辑模式和运行时获得缺少参数的警告。
跨场景引用——将对象分配给其他场景的字段。
服务标签——从上下文菜单将任何组件变成服务。

代码特性:

[Service]属性——轻松创建全局共享服务,并自动注入客户端。
带参数的AddComponent。
带参数的Instantiate。
带有组件和参数的新GameObject。
智能执行顺序——根据它们的依赖项对对象进行初始化,避免执行顺序相关的问题。
Null / NullOrInactive——轻松测试接口类型变量是否包含一个已销毁的对象。
包装器——将普通的C#对象附加到游戏对象。
只读支持——在初始化期间为只读字段和属性分配值。
此外,还包含一个带有完全功能的示例游戏的演示场景!

Leave a Reply

后才能评论