unity strangeioc框架 怎么删除

Unity StrangeIoc框架 (三)signal信号方式 - Sun‘刺眼的博客 - 博客园
随笔 - 732, 文章 - 0, 评论 - 25, 引用 - 0
先创建TestRoot
using UnityE
using System.C
using strange.extensions.context.
public class TestRoot : ContextView {
void Start()
context = new TestContext(this);
创建TestContext&& 在TestContext中我们需要把事件命令修改为 信号命令
using UnityE
using System.C
using strange.extensions.context.
using strange.extensions.context.
using mand.
using mand.
public class TestContext : MVCSContext {
public TestContext(MonoBehaviour view)
: base(view)
public TestContext(MonoBehaviour view, ContextStartupFlags flags)
: base(view, flags)
     override&public&IContext&Start()
&&&&&&& base.Start();
&&&&&&& StartSignal&startSignal&=&(StartSignal)injectionBinder.GetInstance&StartSignal&();
&&&&&&& startSignal.Dispatch();
&&&&&&& return&
protected override void addCoreComponents()
base.addCoreComponents();
injectionBinder.Unbind&ICommandBinder&();
injectionBinder.Bind&ICommandBinder&().To&SignalCommandBinder&().ToSingleton();
protected override void mapBindings()
injectionBinder.Bind&SuccessSignal&().ToSingleton();&&&&&&& injectionBinder.Bind&IService&().To&TestService&();&&&&&&& mediationBinder.Bind&TestView&().To&TestMediator&();&&&&&&& commandBinder.Bind&RequestSignal&().To&RequestCommand&();&&&&&&& commandBinder.Bind&StartSignal&().To&StartCommand&().Once();
strange中IcommandBinder 事件绑定是在addCoreComponents中进行的 所以我们重写他 调用它原本的方法 再将ICommandBinder移除,在将他绑定到信号上signalCommandBinder& 重写Start()& 然后派发& 这样就完成了&&&&&&& 最后在mapBinding中进行之前一样的绑定 。
我们写一个脚本 把所有的信号都放在里面。&& 在具体情况中可以分模块将信号放在一起
  public class StartSignal : Signal
public class ClickSignal : Signal
public class RequestSignal : Signal&string&
public class SuccessSignal : Signal
StartCommand与之前的事件方法没有区别
public class StartCommand : Command
[Inject(ContextKeys.CONTEXT_VIEW)]
public GameObject contextView { }
public override void Execute()
GameObject test = new GameObject("test");
test.AddComponent&TestView&();
test.transform.SetParent(contextView.transform);
TestView 有略微的不同&&& 直接实例信号进行派发
public class TestView : View
public ClickSignal signal_Click = new ClickSignal();
void OnGUI()
if (GUI.Button(new Rect(0, 0, 100, 40), "click"))
signal_Click.Dispatch();
在TestMediator中进行监听& 然后执行方法
public class TestMediator : Mediator
public TestView view { }
public RequestSignal signal_Request { }
public override void OnRegister()
view.signal_Click.AddListener(OnClick);
public void OnClick()
signal_Request.Dispatch("");
当被点击后会进行signal_Request信号的事件派发&& RequestSignal 通过注入获取
在RequestCommand中& 我们service 通过注入获取& 然后对他进行了signal_succesd信号的监听
public class RequestCommand : Command
public IService service { }
public override void Execute()
service.signal_succesd.AddListener(OnComplete);
service.Request();
void OnComplete()
service.signal_succesd.RemoveListener(OnComplete);
Debug.Log("get data finish");
Release();
既然添加了监听 那么肯定有地方会进行成功后的信号派发&&& 在TestService 中& 我们对成功的信号进行派发
public class TestService : IService
[Inject(ContextKeys.CONTEXT_VIEW)]
public GameObject contextView { }
public SuccessSignal signal_succesd { }
public void Request()
contextView.GetComponent&MonoBehaviour&().StartCoroutine(Wait());
/// &summary&
/// 模拟网络请求延迟1秒
/// &/summary&
/// &returns&&/returns&
IEnumerator Wait()
yield return new WaitForSeconds(1);
signal_succesd.Dispatch();
这样& 我们就实现了信号的机制& 信号也是官方推荐的方法安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&本文已收录于以下专栏:
相关文章推荐
参考链接:/thread-.html?_dsign=334770ed
一、创建lua脚本模板
在\Editor\Data\Resourc...
原文:http://engineering.socialpoint.es/MVC-pattern-unity3d-ui.html
&#160; &#160; &#160; &#160; 和游戏开发的其他模块类似,UI一般需要通过多次迭...
模型Model脚本(GameModel)using UnityE
using System.C
using System.Collections.G
博客,对程序员来说应该是个特殊、特别的词汇,尤其是对于俺----这只只知道默默的呆在教室的一角,偶尔45度望望天空,装装文艺的小程序猿,不只是为了把程序运行成功后的那份激动分享出来,更希望能在这茫茫人...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)&最近想项目中需要使用这个架构& 因此 上网看了很多资料摸索&& 但是对于初学者来说大多数的资料不是那么容易理解 而且文档也是英文的阅读起来有点吃力& 所以记录一下自己阅读的过程& 方便以后翻阅和跟我一样的新人学习其中也借鉴了一些前辈的资料 如有反感请联系我&& 立马进行修改& 谢谢
文档坐标 &
StrangeIoc 是依据控制反转和解耦原理设计的,支持依赖注入。
控制反转即Ioc(Inversion of Control) 它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所为的&控制反转&概念就是对组件对象控制权的转移,从程序代码本身转移到了内部的容器。
依赖注入(Dependency Injection)&&& 依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的写作对象。配置对象的工作应该由Ioc容器负责,
Bingding(绑定)
strange的核心是绑定,我们可以将一个或多个对象与另外一个或多个对象绑定(连接)在一起,将接口与类绑定来实现接口,将事件与事件接收绑定在一起。或者绑定两个类,一个类被创建时另一个类自动创建。
strange的binding由两个必要部分和一个可选部分组成,必要部分是a key and a value &key触发value,因此一个事件可以触发回调,一个类的实例化可以触发另一个类的实例化。可选部分是name,他可以区分使用相同key的两个binding 下面三种绑定方法其实都是一样的,语法不同而已
1. Bind&IRoundLogic&().To&RoundLogic&();
2. Bind(typeof(IRoundLogic)).To(typeof(RoundLogic));
3. IBinding binding = Bind&IRoundLogic&();
//使用IBinding 的时候需要引用strange.framework. 命名空间
binding.To&RoundLogic&();Bind&IRoundLogic&().To&RoundLogic&().ToName(&Logic&);    //使用非必要部分name
绑定从层次上分为
commandbinding是为了将命令绑定到方法中用的
mediationbing则是为了拦截
The injection extension(注入扩展)
在绑定扩展中最接近控制反转的思想是注入
接口本身没有实现方法,只定义类中的规则
interface ISpaceship
void input(float angle, float velocity);
IWeapon weapon{get;set;}
//使用另一个类实现这个接口,写法如下
Class Spaceship : ISpaceship
public void input(float angle, float velocity)
public IWeapon weapon{get;set;}
如果采用上面的写法,Spaceship类里面不用再写检测输入的功能了,只需要处理输入就可以了input只需要控制移动,不需要管是何种输入方式& 是手柄键盘或是其他& 只需要进行处理
也不需要武器的逻辑,仅仅是注入武器实例就可以了。但是我们需要知道武器是什么样的武器 不同的武器造成不同的掉血& 所以这块的逻辑是需要处理的
public interface IWeapon
void Attack();
public class PhaserGun : IWeapon
public void Attack(){//掉血逻辑
public class SquirtCannon : IWeapon
public void Attack(){//掉血逻辑
在ISpaceship中的代码进行一点修改
interface ISpaceship
void input(float angle, float velocity);
IWeapon weapon{get;set;}
加上Inject标签& 这样就可以进行绑定了&& 将接口与类绑定来实现接口
[Inject]标签实现接口,而不是实例化类
injectionBinder.Bind&IWeapon&().To&PhaserGun &();
injectionBinder.Bind&IWeapon&().To&PhaserGun &().ToStringleton();IWeapon weapon = PhaserGun.Get();
在绑定多个的时候就需要利用& 名称映射来进行区分
injectionBinder.Bind&ISocialService&()
.To&TwitterService&().ToSingleton()
.ToName(ServiceTypes.PRIMARY);
injectionBinder.Bind&ISocialService&()
.To&TwitterService&().ToSingleton()
.ToName(ServiceTypes.SECONDARY);
injectionBinder.Bind&ISocialService&()
.To&TwitterService&().ToSingleton()
.ToName(ServiceTypes.TERTIARY);
在[Inject]标签处 也需要进行添加名称
[Inject (ServiceTypes.TERTIARY)] //We mapped TwitterService to TERTIARY
public ISocialService socialService{get;set;}
Configuration myConfig = loadConfiguration();
injectionBinder.Bind&IConfig&().ToValue(myConfig);
具体还有几种映射就不说了& 需要的可以去看看文档
&The reflector extension(反射扩展)
List&Type& list = new List&Type& ();
list.Add (typeof(Borg));
list.Add (typeof(DeathStar));
list.Add (typeof(Galactus));
list.Add (typeof(Berserker));
//count should equal 4, verifying that all four classes were reflected.
int count = injectionBinder.Reflect (list);
反射所有已经通过injectionBinder映射的所有
injectionBinder.ReflectAll();
The dispatcher extension(调度程序扩展)
dispatcher相当于观察者模式中的公告板,允许客户监听他,并且告知当前发生的事件。在strangeioc中,通过EventDispatcher方式实现,EventDispatcher绑定触发器来触发带参数/不带参数的方法&& 触发器通常是String或枚举类型(触发器可以理解为key,或者事件的名称,名称对应着触发的方法)
如果有返回值,他将存在IEvent,一个简单的值对象包含与该事件相关的任何数据,你可以写你自己的事件满足IEvent接口,strangeioc事件叫TmEvent
如果你再使用MVCSContext 有一个全局的EventDispatcher 叫contextDispatcher 会自动注入,你可以用来传递事件
有两种基本的事你可以去做EventDipatcher调度事件和监听他们
dispatcher.AddListener("FIRE_MISSILE", onMissileFire);
事件会处于监听状态,知道FIRE_MISSILE事件被处罚,然后执行对应的onMissileFire方法
也可以通过枚举实现
dispatcher.AddListener(AttackEvent.FIRE_MISSILE, onMissileFire);
dispatcher.RemoveListener(AttackEvent.FIRE_MISSILE, onMissileFire);
dispatcher.UpdateListener(true, AttackEvent.FIRE_MISSILE, onMissileFire);
调用的方法可以有一个参数或者没有,这取决于你关心的事件效率
private void onMissileFire()
//this works...
private void onMissileFire(IEvent evt)
//...and so does this.
Vector3 direction = evt.data as Vector3;
dispatcher.Dispatch(AttackEvent.FIRE_MISSILE);
这种形式的调度将生成一个新的TmEvent& 调用任何监听对象,但是因为你没有提供数据,数据字段的TmEvent当然会是零。 你也可以调度和提供数据:
Vector3 orientation = gameObject.transform.localRotation.eulerA
dispatcher.Dispatch(AttackEvent.FIRE_MISSILE, orientation);
可以自己创建TmEvent调度
Vector3 orientation = gameObject.transform.localRotation.eulerATmEvent evt = new TmEvent(AttackEvent.FIRE_MISSILE, dispatcher, this.orientation);
dispatcher.Dispatch(evt);
&The command extension(命令扩展)
&除了绑定事件的方法,可以将其绑定到Commands。命令是控制器结构MVC的指挥者在strangeioc的MVCSContext中 CommandBinder监听每一个dispatcher的调度(当然你可以改变这个如果你想在自己的上下文)。信号,下面描述,也可以绑定到命令。当一个事件或信号被调度,
using mand.
using com.example.spacebattle.
namespace com.example.spacebattle.controller
class StartGameCommand : EventCommand
public ITimer gameTimer{get;set;}
override public void Execute()
gameTimer.start();
dispatcher.dispatch(GameEvent.STARTED);
但异步命令, 像网络请求&& 可以这样做&& Retain() and Release()
using mand.
using com.example.spacebattle.
namespace com.example.spacebattle.controller
class PostScoreCommand : EventCommand
IServer gameServer{get;set;}
override public void Execute()
int score = (int)evt.
gameServer.dispatcher.AddListener(ServerEvent.SUCCESS, onSuccess);
gameServer.dispatcher.AddListener(ServerEvent.FAILURE, onFailure);
gameServer.send(score);
private void onSuccess()
gameServer.dispatcher.RemoveListener(ServerEvent.SUCCESS, onSuccess);
gameServer.dispatcher.RemoveListener(ServerEvent.FAILURE, onFailure);
//...do something to report success...
Release();
private void onFailure(object payload)
gameServer.dispatcher.RemoveListener(ServerEvent.SUCCESS, onSuccess);
gameServer.dispatcher.RemoveListener(
ServerEvent.FAILURE, onFailure);
//...do something to report failure...
Release();
如果使用完不进行Release()可能会导致内存泄露&
commandBinder.Bind(ServerEvent.POST_SCORE).To&PostScoreCommand&();
您可以将多个命令绑定到单个事件如果你喜欢
commandBinder.Bind(GameEvent.HIT).To&DestroyEnemyCommand&().To&UpdateScoreCommand&();
解除命令绑定Unbind
commandBinder.Unbind(ServerEvent.POST_SCORE);
一次性的指令
commandBinder.Bind(GameEvent.HIT).To&DestroyEnemyCommand&().Once();
按顺序执行绑定&& InSequence& 会一直执行到最后的命令 或者其中一个命令失败。& 命令可以在任何时候调用Fail()&& 这会打破这个序列& 这可以用于建立一个链相关的事件& 为构建有序的动画,或制定一个守卫,以确定是否应该执行一个命令。
commandBinder.Bind(GameEvent.HIT).InSequence()
.To&CheckLevelClearedCommand&()
.To&EndLevelCommand&()
.To&GameOverCommand&();
&The signal extension(消息扩展)
信号是一个调度机制,另一种选择EventDispatcher 相比于EventDispatcher& 信号有两个优点& 1. 分发结果不再创建实例,因此也不需要GC回收更多的辣鸡& 2. 更安全 当消息与回调不匹配时会断开执行,官网也推荐使用Singal来兼容后续版本
创建两个信号,每一个都有一个参数
Signal&int& signalDispatchesInt = new Signal&int&();
Signal&string& signalDispatchesString = new Signal&string&();signalDispatchesInt.AddListener(callbackInt);      //Add a callback with an int parametersignalDispatchesString.AddListener(callbackString);    //Add a callback with a string parametersignalDispatchesInt.Dispatch(42);        //dispatch an intsignalDispathcesString.Dispatch("Ender wiggin");      //dispatch a stringvoid callbackInt(int value){    //Do something with this int}void callbackString(string value){    //Do something with this string}
消息最多可以使用四个参数
Signal&T, U, V, W& signal = new Signal&T, U, V, W&();
子类可以编写自己的信号
using UnityE
using strange.extensions.signal.
namespace mynamespace
//We're typing this Signal's payloads to MonoBehaviour and int
public class ShipDestroyedSignal : Signal&MonoBehaviour, int&
信号映射到命令
protected override void addCoreComponents()
base.addCoreComponents();
injectionBinder.Unbind&ICommandBinder&();
injectionBinder.Bind&ICommandBinder&().To&SignalCommandBinder&().ToSingleton();
这告诉strangeioc 我们做了默认CommandBinder SignalCommandBinder取而代之。 所以是信号触发命令 而不是事件 。 strangeioc& 只支持 事件或者信号中的一个映射命令,而不是两个都是。
信号绑定&& 依旧使用commandBinder
commandBinder.Bind&SomeSignal&().To&SomeCommand&();
映射一个信号到命令& 会自动创建一个injection映射& 你可以通过[Inject]标签 检索
public ShipDestroyedSignal shipDestroyedSignal{get; set;}
commandBinder.Bind&ShipDestroyedSignal&().To&ShipDestroyedCommand&();
在ShipMediator,我们注入信号,然后调度
public ShipDestroyedSignal shipDestroyedSignal{get; set;}
private int basePointV //imagining that the Mediator holds a value for this ship
//Something happened that resulted in destruction
private void OnShipDestroyed()
shipDestroyedSignal.Dispatch(view, basePointValue);
派遣一个信号通过SignalCommandBinder映射结果的实例化ShipDestroyedCommand:
using mand.
using UnityE
namespace mynamespace
//Note how we extend Command, not EventCommand
public class ShipDestroyedCommand : Command
public MonoBehaviour view{ get; set;}
public int basePointValue{ get; set;}
public override void Execute ()
//Do unspeakable things to the destroyed ship
如您所见,映射的方法非常类似于信号命令的方法使用事件
两个重要问题:第一,而信号支持多个相同类型的参数,注射。 因此不可能对一个信号与相同类型的两个参数映射到一个命令
//This works
Signal&int, int& twoIntSignal = new Signal&int, int&();
twoIntSignal.AddListener(twoIntCallback);
//This fails
Signal&int, int& twoIntSignal = new Signal&int, int&();
commandBinder.Bind(twoIntSignal).To&SomeCommand&();
override public void Launch()
base.Launch();
//Make sure you've mapped this to a StartCommand!
StartSignal startSignal= (StartSignal)injectionBinder.GetInstance&StartSignal&();
startSignal.Dispatch();
映射没有命令的信号&
一个信号映射到一个命令会自动创建一个映射,您可以检索通过注入到其他地方&& 但是如果你想注入信号没有绑定到一个命令& 使用injectionBinder只需将它映射
injectionBinder.Bind&ShipDestroyedSignal&().ToSingleton();
The mediation extension(调解器(中介模式))
MediationContext是唯一一个专为unity设计的部分,因为mediation关心的是对view(GameObject)的操作。由于view部分天生的不确定性,我们推荐view由两种不同的monobehavior组成:View and Mediator
view就是mvc中的v,一个view就是一个你可以编写的逻辑,控制可见部分的monobehavior 这个类可以附加(拖拽)到unity编辑器来管理GameObject 但是不建议将mvc中的models和controller逻辑卸载view中
Mediator类的职责是执行view和整个应用的运行。他会获取整个app中分发和接收时间和消息。但是因为mediator的设计,建议使用命令模式(command)来做这部分功能
using Strange.extensions.mediation.
using com.example.spacebattle.
using com.example.spacebattle.
namespace com.example.spacebattle.view
class DashboardMediator : EventMediator
public DashboardView view{get;set;}
override public void OnRegister()
view.init();
dispatcher.AddListener
(ServiceEvent.FULFILL_ONLINE_PLAYERS, onPlayers);
dispatcher.Dispatch
(ServiceEvent.REQUEST_ONLINE_PLAYERS);
override public void OnRemove()
dispatcher.RemoveListener
(ServiceEvent.FULFILL_ONLINE_PLAYERS, onPlayers);
private void onPlayers(IEvent evt)
IPlayers[] playerList = evt.data as IPlayers[];
view.updatePlayerCount(playerList.Length);
1.DashboardView注入可以使 Mediator 知道具体的view
2.注入完成后OnRegister()方法会立即执行,可以用这个方法来做初始化& 像上面做的那样 初始化 然后做重要的数据请求
3.contextDispatcher可以扩展任何的EventMediator
4.OnRemove()清理时使用,当一个view销毁前被调用,移除时记得删除你的监听
5.例子中的view暴露两个接口init()和updatePlayerCount(float value),但是程序在设计时 你需要更多,但是原则是相同的& 限制中介除了薄任务之间的传递信息的查看和其他应用程序
绑定一个界面到Mediator
mediationBinder.Bind&DashboardView&().To&DashboardMediator&();
值得注意的几点
1.不是所有的MonoBehaviour被限制为一个View&
2.中介者绑定是实例对实例的,也就是说一个view对应一个mediator,如果有很多view,也就会有很多的mediator
The context extension(上下文扩展)
MVCSContext包含EventDispatcher(事件分发),injectionBinder(注入绑定),MediationBinder(中介绑定),CommandBinder(命令绑定)
可以重新将CommandBinder绑定到SignalCommandBinder&& 命令和中介依托注入,context可以为命令和中介的绑定提供关联
建立一个项目,需要重新MVCSContext或者Context,一个app也可以包换多个Contexts 这样可以使你的app更高的模块化,因此,一个app可以独立的设计为聊天模块,社交模块& 最终他们会整合到一起成为一个完整的app
暂时记录到这里 剩下的 下一章补完
阅读(...) 评论()

我要回帖

更多关于 strangeioc demo 的文章

 

随机推荐