Unity框架探索——StrangeIOC篇

前言

unity的框架,除了各大公司本身内部使用的,开源并好用的实际并非不少,我会慢慢挖掘,依次写出本身的一点看法,错误的地方,望各路大神指正。java

1、基本概念

控制反转(Inversion of Control,英文缩写为IOC),个人理解就是,本来A类要获取B类的对象,须要你在A类中本身New一个对象,那么是由A来获取并控制B的对象,IOC就是把对象获取的这个过程交给容器和依赖注入来处理,A类并不知道B的对象是哪里来的,对B对象的控制,由本身变成了其余类,官方一点的概念能够百度,这个仍是蛮多的。web

2、StrangeIOC基础类型

实际要理解一个框架的类型,仍是要本身看源码,这里我只说一下几个重要类型的做用,这个看源码的时候有个印象,也方便理解,并且说这部分的帖子也不少,我就再也不赘述了。服务器

1.Context

上下文组件定义程序边界,也就是能够把一个程序定义成多上下文,让代码更加模块化
它提供了程序入口,也算是框架中耦合度最高的地方微信

2.Binder和Binding

这两个类是这个框架最重要的组成部分
Binding存储了对象的绑定关系,而Binder存储了Binding的对象框架

3.View和Mediator

MVCS中的View层,View只用于显示,也就是View只负责管理UI,Mediator负责界面逻辑,事件响应等svg

4.Model

MVCS中的Model层,负责数据部分模块化

5.Command

MVCS中的Control层,负责执行逻辑代码函数

6.Service

MVCS中的Service层,负责与第三方交互,这个Service我理解的,并非必定指代服务器,也能够是其余的软件,什么均可以,它就是咱们程序对外的接口spa

7.Dispatcher

派发器是框架内通讯主线的其中一种,用来派发消息,触发命令,从而进一步解耦.net

8.Signal

信号是框架内另一种通讯主线,它采用强类型,来绑定信号和命令之间的关系,实现消息响应的触发

9.ReflectionBinder

反射部分,经过binding来获取类的信息,存储在ReflectedClass中

10.injector

注入器,经过反射获取的信息,来实例化请求的对象

2、StrangeIOC的执行流程

我主要想写的是这个部分,其余的帖子不多有说明框架内部具体的运行机制和运行流程的
下面我就一步步介绍框架内部的主要执行流程

1.CustomContext

CustomContext是咱们本身建立的上下文类型,继承自MVCSContext,会在咱们自建建立的ContextView中执行,这就是程序的惟一入口
而CustomContext的基类Context的构造中,调用了两个方法
[外链图片转存失败(img-n8k60PNC-1566895102644)(https://i.loli.net/2018/07/01/5b388eafb7b6a.jpg)]
其中Start方法,是框架初始化的重要方法

因此,若是有须要重写Start方法的地方,必定不要忘记base.Start();,否则会出问题
其中,instantiateCoreComponents()是实例化核心组件的

它生成了全部这些核心组件的实例

而addCoreComponents()就是来指定核心组件的绑定关系的

你必定注意到了,全部的绑定关系都是由injectionBinder来存储的,那么这个injectionBinder是怎么来的呢?

2.injectionBinder

这个Binder对象是在CrossContext中的属性中,本身new出来的,并无依靠依赖注入

而在CrossContextInjectionBinder的基类InjectionBinder中能够看到注入部分所需的组件,都是在它的构造中自动生成的

很明显,injectionBinder是框架全部组件初始化的关键,其余的核心组件的实例化都是由它来完成的

3.核心组件的初始化

1)View和Mediator
View和Mediator比较特殊,由于是要挂载到GameObject上的
首先,View脚本会执行它本身的Awake()和Start()
这两个方法中,都调用了bubbleToContext方法,View使用这个函数,把本身添加到当前上下文中

在AddView中,调用mediationBinder的Trigger

而后在Trigger中

injectViewAndChildren就是用来实现注入操做的,这里等下详细说

mapView就是用来添加Mediator的

这里就完成了视图层的系统组件初始化流程
2)commandBinder
通讯管线须要绑定Command
而框架内有两种通讯管线
第一种:


这种是默认写法,就是用dispatcher(派发器)派发信号,来触发命令
派发器的初始化:
[外链图片转存失败(img-t4aaBtgY-1566895102647)(https://i.loli.net/2018/07/01/5b38c63bb3265.jpg)]
这两行代码在dispatcher中注册了触发器
dispatcher中使用triggerClients保存了注册的触发器

派发器的执行流程:
咱们使用派发器的时候,是用Dispatch方法派发事件
在Dispatch方法中,把事件分发给注册过的触发器

而CommandBinder的Trigger方法,会执行ReactTo方法



[外链图片转存失败(img-EK2F3eLL-1566895102648)(https://i.loli.net/2018/07/01/5b38c8db80d0d.jpg)]
第二种
就是用信号来触发命令,这种方式的实现,须要修改部分代码

如上图,须要解绑本来的ICommandBinder,并绑定为SignalCommandBinder
这样commandBinder才能实现信号的绑定
初始化:

bind方法会依次调用父类bind方法,调用到Binder

这里起到的做用是生成新的binding对象,来存储传进来的key值,而在生成binding的过程当中,还绑定了这个binding的resolver(分析器)

这个resolver中,执行了ResolveBinding方法

而SignalCommandBinder的ResolveBinding方法,给提供的signal绑定了ReactTo方法

信号触发执行流程:
信号的触发,就是调用信号的Dispatch方法
而初始化时,signal绑定了ReactTo,以后命令的执行流程就和派发器同样了

4.注入流程

不管在哪一个组件中,都会存在injectionBinder对象

实现注入就须要使用injectionBinder对象,有两种实现注入的流程
一种是向在MedaitorBinder中同样直接调用

或者像CommandBinder这样


获取到Injector对象之后,调用Instantiate方法

而在Inject方法和Instantiate方法中,都有这句代码

这句就是经过类型,获取反射信息的代码,获取反射信息以后
而在Inject中,调用了这样两个方法

以上就是框架内核心部分的执行流程

3、StrangeIOC的绑定部分

IOC框架是须要提早配置绑定关系的,像java中,不少框架是用配置文件,StrangeIOC中,是在代码中进行绑定
在本身写的继承自MVCSContext的类中,须要本身重写mapBindings方法,这个方法的内容,就是配置绑定关系
1.绑定View和Medaitor,要使用mediationBinder

To< M>:类型M必须是继承自Mediator的类型
2.绑定Command,要使用commandBinder
1)若是是用派发器触发命令
能够这样写

Bind(key).To< C>
key能够是字符串,枚举等
C必须是实现了ICommand的实体类
2)若是是用信号触发命令
能够这样写

Bind< S>().To< C>
S: 必须是Signal
C:必须是ICommand的实体类

以上就是我本身对这个框架的一点了解,总的来讲,IOC框架对于解耦作的仍是比较好的,可是也常常会形成调试的难度,可是这个能够用规范的代码来下降风险,因此这个框架仍是值得使用的。

StrangeIOC每一个层的脚本基本都是成对出现的,好比咱们写Player功能,须要生成PlayerView,PlayerModel,PlayerService等等,我本身写了一个插件,用于一键自动生成一套脚本,详见:自动建立框架配套脚本

我会在个人公众号上推送新的博文,也能够帮你们解答问题
微信公众号 Andy and Unity 搜索名称或扫描二维码
在这里插入图片描述 但愿咱们能共同成长,共同进步