StrangeIOC使用流程(一)

首先这个框架可以在assetStore上下载到, 也可以在GitHub上获取,直接搜索StrangeIOC就可以, AssetStore上下载的更简洁,除了有一个examples 其余都是框架脚本, GitHub上下载的则有更多的学习文档以及其他附带的东西.. 先附两张图

1、Root  是整个框架的起点,是挂在物体上的,继承自ContextView 间接继承自MonoBehavior 他的主要功能是创建Context(环境) 

public class Demo1ContextView : ContextView {


private void Awake()
{
this.context = new Demo1Context(this);
}
}

2,接着创建一个Demo1Context 继承MVCSContext   主要用来绑定  需要实现父类的构造函数和一个绑定函数

public class Demo1Context : MVCSContext {
public Demo1Context(MonoBehaviour view) : base(view) { }

/// <summary>
/// 四种绑定
/// 1.model (M)
/// 2.serivce (S)
/// 3.command (C)
/// 4.mediator (V)
/// </summary>
protected override void mapBindings()
{

/// 四种绑定
/// 1.model (M)
/// 2.serivce (S)
/// 3.command (C)
/// 4.mediator (V)

//创建一个StartCommand 在上边的绑定初始化后进行调用
//commandBinder.Bind(ContextEvent) //把一个命令和一个枚举类型做绑定, 枚举类型已经提供
commandBinder.Bind(ContextEvent.START).To<StartCommand>().Once();// 把某个事件和某个Command绑定上,这个是StrangeIOC框架绑定开始事件, 自动调用StartCommand命令(会调用这个命令中的Execute方法) 只触发一次后解绑


}
}

3,创建一个控制器继承Command类,

public class StartCommand : Command {

public override void Execute()
{
Debug.Log("被调用");
}

}

4.创建model层  用来存储数据

public class ScoreModel{
public int score { get; set; }
}

5创建service 层

先有接口, 再去做实现, 可以在后期项目做接口变动时只修改实现就可以了

public interface IScoreService {
void RequestScore(string url); // 取得分数 //异步方法,没有返回值

void OnReceivesScore();//收到上边方法调用后 服务器端发送来的分数

void UpdataScore(string url, int score);//更新分数 服务器地址, 更新到服务器分数

}

6,实现service接口  ///虚拟数据, 暂时不含服务器通讯

public class ScoreService : IScoreService
{

public void RequestScore(string url)
{
Debug.Log("向地址" + url + "发送请求分数");
OnReceivesScore();
}

public void OnReceivesScore()
{
int score = Random.Range(0, 100);//模拟分数
}

public void UpdataScore(string url, int score)
{
Debug.Log("更新到" + url + "新分数:" + score);
}
}

7.view层,挂在一个游戏物体上

public class CubeView : View { //此层只做显示, 不知道任何数据也取不到

Text scoreText; //Text 组件, 分数不会在这一层中做处理,而是在model层

void Init()
{
scoreText = GetComponentInChildren<Text>();
}

private void Update()
{
transform.Translate(new Vector3(Random.Range(-1, 2), Random.Range(-1, 2), Random.Range(-1, 2)) * .2f);
}

private void OnMouseDown()
{
Debug.Log("onmousedown");
}

public void UpdateScore(int score)//用来更新分数显示, 不处理分数逻辑 mediator负责调用.,一般一个view对应一个mediator...mediator是什么..看CubeMediator类
{
scoreText.text = score.ToString();
}
}

8.View的中介层 Mediator

public class CubeMediator : Mediator { //用来处理CubeView和外界的交互,这个类需要在Context中注册到一个View层的类中,让框架进行匹配或者说处理 //这个类会在绑定后自动添加到绑定的对象(gameObject)上;

[Inject] //对一个属性进行注入 注入后StrangeIOC会自动对这个属性进行赋值 .目的是减少层与层之间的交互
public CubeView cubeView { get; set; }

public override void OnRegister() //在所有属性注入完成后会自动调用,保证能够访问到属性
{
Debug.Log(cubeView.name);
cubeView.Init();
}

public override void OnRemove()//当mediator对应的view被销毁时自动调用(经过测试没有被调用)-未解
{
Debug.Log(this.name);
}

}

9.更新分数的显示-- 通过mediator调用command 通过command调用services的request方法来取得分数,这里需要使用模块与模块之间触发的机制   -- IEventDispatcher 派发器, 这样避免了模块之间直接去调用, 同样是为了解耦

首先创建请求分数的Command层

public class RequestScoreCommand : Command {
public override void Execute() //在mediator里去触发   这个方法去请求服务器里的分数
{
  
}
}

10.然后在CubeMediator中进行修改如下

public class CubeMediator : Mediator { //用来处理CubeView和外界的交互,这个类需要在Context中注册到一个View层的类中,让框架进行匹配或者说处理 //这个类会在绑定后自动添加到绑定的对象(gameObject)上;

[Inject] //对一个属性进行注入 注入后StrangeIOC会自动对这个属性进行赋值 .目的是减少层与层之间的交互
public CubeView cubeView { get; set; }

[Inject] //注入
public IEventDispatcher dispatcher { get; set; }

public override void OnRegister() //在所有属性注入完成后会自动调用,保证能够访问到属性
{
Debug.Log(cubeView.name);
cubeView.Init();

//通过dispatcher 发起请求分数的命令
dispatcher.Dispatch(Demo1CommandEvent.RequestScore);//发起一个Event,这个Event和哪个Command绑定,这个Command就会被调用

}

public override void OnRemove()//当mediator对应的view被销毁时自动调用(经过测试没有被调用)-未解
{
Debug.Log(this.name);
}

}

11新建枚举

public enum Demo1CommandEvent { //这个来保存这个项目中所有命令的事件

RequestScore,

}

12.在Demo1Context中添加绑定

// 3.command (C)
commandBinder.Bind(Demo1CommandEvent.RequestScore).To<RequestScoreCommand>();//把这个事件(枚举类型)和请求分数进行绑定,绑定之后就会自动调用 RequestScoreCommand的Execute方法了

13.RequestScoreCommand类中添加一个注入引用

[Inject]
public IScoreService scoreService { get; set; } //这里由于不像CubeMediator 在注入CubeView的时候 因为CubeView是挂到游戏物体上的,获得的注入唯一.这个接口可能有很多实现, 所以需要通过注入绑定的方式进行指定

14.注入绑定,在Demo1Context类中

// 2.serivce (S)

injectionBinder.Bind<IScoreService>().Bind<ScoreService>().ToSingleton();// 注入绑定指定实现的类,当需要注入IScoreService的时候才能确定,因为model和service只需要一个对象(数据和服务器请求,不像挂载游戏物体产生多个实例)所以可以通过.ToSingleton设置为单例只在工程中生成一个

15.注入后就可以在requestScoreCommand类中的Execute方法中调用了

public class RequestScoreCommand : Command {

[Inject]
public IScoreService scoreService { get; set; } //这里由于不像CubeMediator 在注入CubeView的时候 因为CubeView是挂到游戏物体上的,获得的注入唯一.这个接口可能有很多实现, 所以需要通过注入绑定的方式进行指定
public override void Execute() //在mediator里去触发 这个方法去请求服务器里的分数
{
scoreService.RequestScore("http:xxxx.x.x.x.");
}
}

这里会有一个问题.由于在CubeMediator中的dispatcher派发器是类中的(局部的),会导但是派发器在CubeMediator发起请求的时候不会被调用,所以必须使用全局的派发器,在注入绑定时加一个标示就行了

[Inject(ContextKeys.CONTEXT_DISPATCHER)] //注入的方式拿到派发器类(其实是个接口)的引用 (括号中为设置成全局的派发器)

public IEventDispatcher dispatcher { get; set; }  //声明一个派发器

到这里 就完成了调用服务器之前的事情. 可以发现所有类之间并没有直接联系.都是通过注入的形式去调用  附上工程链接,后续更新

https://pan.baidu.com/s/15DcIpjOPhitvhekdJ45GcQ

本博客所有内容均为原创,转载请注明出处.
原文地址:https://www.cnblogs.com/what-lee/p/9292683.html