StrangeIoc是一款基于MVCS的一种框架,是对MVC思想的扩展,是专门针对Unity3D开发的一款框架,很是好用。服务器
MVCS框架是一种模块的分离,一种写代码的规则,目的是便于代码的管理修改,更有利于编码思惟。将UI和逻辑分开,StrangeIoc框架就很好地实现了UI和逻辑的分离以及各个模块的分离。mvc
一、M 即Model层:是本地数据类型的容器,好比从服务器、表、xml等得到的数据赋值给model,之后再取用数据时直接读取model对象便可。通常为单例的对象。框架
二、V 即View层:是视图,通常指UI,在StrangeIoc中View通常以组件的形式挂在物体身上的,负责查找UI上须要交互的对象。而且在view中提供更新UI的方法。View层又分为负责纯UI的View层和负责交互的Mediator层。函数
三、C 即Command层:是一个个命令,这些命令在Context中会和事件绑定,绑定后只要触发事件就会执行对应的Command,Command是框架的核心 负责和service层、model层 以及 Mediator(中间层)的交互。性能
四、S 即Service层:是服务层 ,和服务端进行交互的层,在Service层中定义了一些向服务端请求数据,更新数据,保存数据等方法,这些方法由Command层调用。测试
一、首先自定义一个ContextView类的派生类(如MyContextView),和一个MVCSContext类的派生类(如MyContext),建立一个MyContext对象赋值给MyContextView的继承属性context,MyContext类负责进行一系列的Bind,绑定以后当绑定的类进行建立时,被绑定的类会按照指定的规则自动建立(是否为单例,指定名称等);编码
二、启动context(建立MyContext对象时可选择是否自动启动),此时会触发ContextEvent.START事件。能够在MyContext中绑定ContextEvent.START事件到一个命令,用来执行一些初始化操做(如对一些单例进行初始化),Once()指的是触发一次后就解绑: commandBinder.Bind(ContextEvent.START).To<StartCommand>().Once(); 三、依赖注入:对Mediator、Command等层中的类中的属性打[Inject]注入标记,好让StrangeIoc自动为该属性进行赋值。
四、当View类的派生类被建立时(如MyView1,它们通常事先挂载在UI物体上),和MyView1绑定的Mediator派生类(如MyView1Mediator)也会被建立(自动挂载到该UI物体上),而且自动执行OnRegister方法。在MyView1Mediator类中的OnRegister方法内,能够调用MyView1类中的方法来进行UI更新,也能够经过dispatcher触发指定的事件,事件触发后会自动调用与该事件绑定的Command派生类中的Execute()方法。spa
五、Command派生类又能够和Service的派生类、Model的派生类进行交互。
一、Bind,StrangeIoc提供了绑定的功能(链式调用的形式),在MVCSContext派生类中作绑定,能够绑定类和类,接口和类,类和方法,事件和命令等等,均可以进行绑定,而且能够指定绑定后的规则(是否为单例,是否执行一次后销毁,指定name等)。code
如:commandBinder.Bind(ContextEvent.START).To
二、经过Bind把事件绑定给command后,就能够经过dispatcher触发绑定事件来启动一个command,command启动时会自动执行Execute()方法。也能够经过dispatcher.AddListener()方法来给指定事件注册监听回调函数 三、自定义的Command派生类能够继承自EventCommand类,它继承自Command类,EventCommand内定义了一个全局的dispatcher
四、Inject,Inject就是注入,StrangeIoc是依赖注入的框架,他的功能就是咱们想得到某种类型的对象时不须要本身去建立,只要加上[Inject]标识就能够根据你bind时的规则得到对象。
五、Mediator,中间层,负责和UI、Command之间交互。他的功能就是隔离了UI和逻辑。UI只能和Mediator交互。
六、dispatcher是事件触发器,是StrangeIOC实现的消息发送机制,触发事件后会自动调用和该事件类型绑定的Command(或者调用在事件上注册的回调函数)。分为全局dispatcher和局部dispatcher,它们的区别:
a.能够在任何地方定义一个变量来引用全局的dispatcher,因此经过全局dispatcher注册的事件回调,天然就能够在任何地方触发了。 b.局部的dispatchar只是一个单独的IEventDispatcher的实例,要注册、触发事件就必须先拿到该dispatchar的引用。 c.不论是全局的,仍是局部的dispatchar,它都只能触发在它自身上已经注册的事件。
7.View中的UI层继承自View类,mediator层继承自Mediator类,而View和Mediator都继承自MonoBehaviour类,因此UI层和mediator层的类一样继承了Awake和Start方法,在重写view层的Start方法时,须要注意,必定要先执行他父类的方法base.Start();若是不先执行,就没办法自动建立改View中对应的meidator,自动建立是在框架中执行的。
1.通常不推荐在UI层进行依赖注入,官方推荐的在mediator层进行注入,UI去和mediator层交互。在View中注入的数据在Awake方法中是调用不到的 会报空引用,由于,数据的注入执行顺序在Awake以后,在Start以前。从而能够看出,mediator层的OnRegister方法是晚于Awake执行,早于Start方法的。
2.用dispatcher.AddListener()注册一个事件后,就要有对应的dispatcher.RemoveListener()来删除这个事件监听(通常在游戏销毁的OnRemove()方法内,或回调函数内定义)。 3.Command类中有一个Retain()方法,能够在执行该命令期间,保持该Command的实例不被销毁,这个颇有用,能够确保回调函数的执行,通常在Execute()中使用。对应的有 Release()方法,释放该Command实例,销毁它,通常使用在回调函数中。 4.测试时,若是发现事件没有触发,那就检查你注册该事件的dispatcher和你用来触发事件的dispatcher是否对应(局部or全局?)。
应尽可能避免使用StrangeIoc的依赖注入:这点很重要,由于经过StrangeIoc依赖注入时,涉及到序列化和反序列化,这会下降性能,因此对于那些须要单例的类最好在类中本身实现,把单例的初始化放在StartCommand中,如:AudioManager.Instance.Init();,这样就省去了绑定生成单例和依赖注入的过程,稍微提升了性能。