injectionBinder.Bind<IPositionServise>().To<LinePositionServise>().ToSingleton().CrossContext();
加上CrossContext()就可以声明这个绑定是跨上下文的,也就是说在别的Context下也可以通过IPositionServise类型来注入LinePositionServise实例。(没试验过)
先看一下绑定
protected override void mapBindings() { injectionBinder.Bind<CameraInitSignal>().ToSingleton();//不声明为单例好像就不行 mediationBinder.Bind<CamerView>().To<CamerViewMediator>(); commandBinder.Bind<CameraInitSignal>().To<CameraInitCommand>(); }
View接收到用户的命令交互,发送命令给Mediator
using strange.extensions.mediation.impl; using strange.extensions.signal.impl; public class CamerView : View { //实例化一个局部的Signal,相当于局部的dispatcher public Signal<int> ViewInitSignal = new Signal<int>(); private void OnMouseDown() { //发送命令 ViewInitSignal.Dispatch(10); } }
Mediator层
using UnityEngine; using strange.extensions.mediation.impl; public class CamerViewMediator : Mediator { [Inject] public CamerView View { get; set; } [Inject]//通过注入的方式获取全局的Signal public CameraInitSignal signal { get; set; } public override void OnRegister() { //为View局部的Signal监听 View.ViewInitSignal.AddListener(OnCameraInit); } private void OnCameraInit(int num) { Debug.Log(10); //发送全局的Signal,调动绑定好的Command signal.Dispatch(num); } }
Command层
using UnityEngine; using strange.extensions.command.impl; public class CameraInitCommand : Command { [Inject]//注入的方式获取传递的参数 public int Num { get; set; } public override void Execute() { Debug.Log("Hello World Signal" + Num); } }
剩下回调什么的就没必要继续了,主要想说说的是一个局部的Signal,和一个全局的Signal,还有前面Event没有提到的全局事件的传参,都是通过注入的方式,对应上类型就行,StrangIoc会自动识别的,不需要手动去Bind。
StrangeIoc默认使用的是Event的方式,所以我们要重新绑定一下使用Signal的方式。在MVCSContext下,重写
public override IContext Start() { base.Start(); //程序"起点"的修改,使用StartSignal信号来触发 StartSignal startSignal = (StartSignal)injectionBinder.GetInstance<StartSignal>(); startSignal.Dispatch(); return this; } protected override void addCoreComponents() { base.addCoreComponents(); //先解绑,再重新绑定到SignalCommandBinder injectionBinder.Unbind<ICommandBinder>(); injectionBinder.Bind<ICommandBinder>().To<SignalCommandBinder>().ToSingleton(); } protected override void mapBindings() { //和以前一样绑定,不过Event的枚举变成了刚刚触发的StartSignal commandBinder.Bind<StartSignal>().To<StartCommand>(); }
StrangeIoc支持两种调度方式,一种是事件的形式,一种是使用信号的方式。官方推荐使用的信号的方式。相对于于使用事件,使用信号有这样的优势:
强类型的回调结果,不用强转,也比较安全。
减少垃圾。(还不清楚怎么减少)
private IPositionServise PositionServise; [Construct] public CubeInitCommand(IPositionServise positionServise) { PositionServise = positionServise; }
使用[Construct]特性声明构造方法,如果多个构造方法,不用[Construct]声明哪个的话,就会默认使用参数最少的那个。
IOC是控制反转,我们将代码内的依赖关系交给第三方(IOC容器)管理,需要什么类型时告诉工厂,这个工厂就会成产一个实例提供出来。
绑定Bind,可以理解为往这个IOC工厂内添加接口(值)与类型的映射。
注入也叫依赖注入(DI),就是一个从IOC容器中取值的过程,注入的方式包括:属性注入、接口注入、方法注入。
在对于同一Key要对应不同的Value时,可以通过ToName(object)来命名区别
injectionBinder.Bind<IPositionServise>().To<LinePositionServise>().ToSingleton(); injectionBinder.Bind<IPositionServise>().To<CirclePositionService>().ToSingleton().ToName("Circle");
只要在注入的时候指定相应的名字就可,没有名字的就不用指定
[Inject("Circle")] public IPositionServise PositionServise { get; set; }
绑定是一个Keys对应Value的过程,通过Keys就会得到相应的Value,也就是依赖的绑定,在一个地方,我声明需要这个I接口依赖,这时候就可以通过绑定这个依赖I为具体的实现。
protected override void mapBindings () { //注入绑定,在上下文中,将需要Key类型的值注入为Value的类型实例(这里是单例) injectionBinder.Bind<CubePositionModel>().To<CubePositionModel>().ToSingleton(); injectionBinder.Bind<IPositionServise>().To<LinePositionServise>().ToSingleton(); //View中间层的绑定,CubeView实例化后会自动实例化CubeViewMediator mediationBinder.Bind<CubeView> ().To<CubeViewMediator> (); //命令绑定,key为事件的名称(这里用枚举值表示),Value就是相应的命令Command了 commandBinder.Bind(MCCubeEvent.InitPosition).To<CubeInitCommand>(); commandBinder.Bind(MCCubeEvent.UpdateCunePos).To<CubeUpdateCommand>(); //绑定启动命令,此方法完成后,就会自动分发ContextEvent.START命令 commandBinder.Bind (ContextEvent.START).To<StartCommand> ().Once(); }
Assets下的Demo就是一个Context,分为MVCS目录,我加了一个Event目录,用来保存事件的枚举,其中前缀两个大写应为字母表示是哪两个层的交互事件,后面跟的是哪个对象的事件,最后Event结尾。MVCS就不用多说了,具体的以它的层类型结尾就好了,前缀说明是哪种对象和功能的。
首先是View层被用户交互触发事件,发送命令给Mediator
Mediator接受到命令,发送相应命令给Command
Command层通过Service或Model层得到相应数据,进行处理,发送命令回Mediator
Mediator层接收到回调的数据,更新View