介绍Strange框架的基本方法使用与部署项目
单一绑定。
Bind().To();
Bind(“MeaningOfLife”).To(42);
Bind().To(“Enterprise”);
Bind().To().ToName(“DeepThought”);
Bind().To();
Bind(typeof(IDrive)).To(typeof(WarpDrive));
IBinding binding = Bind();
binding.To();
框架的核心是绑定。
和控制反转(IOC)最密切相关的。
[Inject] //属性标签
public IInterface myInstance {get;set;}
如果你不使用DI,属性标签完全是无害的。所以你可以把它添加到你的类,如果有一天你发现DI不适合你的项目你可以直接将属性的[inject]标签去掉,属性还是普通的get/set
你需要做两件事:
IClass myInstance = injectionBinder.GetInstance() as IClass;
injectionBinder.Bind().To().ToSingleton();
因为Strange的依赖仅仅是一个映射。一旦你使用了DI,你就不在需要使用单例,你只需要使用单例映射。
injectionBinder.Bind()
.To().ToSingleton()
.ToName(ServiceTypes.PRIMARY);
injectionBinder.Bind()
.To().ToSingleton()
.ToName(ServiceTypes.SECONDARY);
injectionBinder.Bind()
.To().ToSingleton()
.ToName(ServiceTypes.TERTIARY);
[Inject (ServiceTypes.TERTIARY)] //We mapped TwitterService to TERTIARY
public ISocialService socialService{get;set;}
注入的名称可以是任何类型,但实际运用中枚举是一个不错的选择。建议谨慎使用此功能。
Configuration myConfig = loadConfiguration();
injectionBinder.Bind().ToValue(myConfig);
myConfig将加载一些配置文件的结果。在你需要的地方使用IConfig,您将收到myConfig值。再一次,请注意,客户端类不知道是否这是一个单例,一个值,等等。它的工作是使用IConfig,而不知道它从哪里来。
TouchCommander instance = TouchCommander.Get();
injectionBinder.Bind().ToValue(instance);
//使用属性注入,使用[Inject] 属性标签。
[Inject]
public ICompensator compensator{get;set;}
//名称注入
[Inject(CompensatorTypes.HEISENBERG)]
public ICompensator compensator{get;set;}
//标记成一个类的类型
[Inject(typeof(HeisenbergMarker))]
public ICompensator compensator{get;set;}
反射是在运行时分析类的过程。StrangeIoC通过这个过程来确定注入内容。
//反射类型列表
List list = new List ();
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);
The
//一切都被映射到了InjectionBinder
injectionBinder.ReflectAll();
StrangeIoc规范的事件叫做TmEvent
EventDipatcher里你要做两个最起初的事情,分派事件与监听
dispatcher.AddListener("FIRE_MISSILE", onMissileFire);
//直到FIRE_MISSILE被调度器调用,OnMissileFire方法才被调用
这样不好,使用字符串作为Key会使代码变得很脆弱,换句话说就是,他们让代码很容易出错。在一个地方一个字符串可以改变代码的其余部分不知晓,这一定是一个灾难。用常量或者枚举会更好:
dispatcher.AddListener(AttackEvent.FIRE_MISSILE, onMissileFire);
dispatcher.RemoveListener(AttackEvent.FIRE_MISSILE, onMissileFire);
dispatcher.UpdateListener(true, AttackEvent.FIRE_MISSILE, onMissileFire);
该命令是先注入,然后执行,最后释放。
CommandBinder 监听着每个调度,Signals也可以绑定到命令。
using strange.extensions.command.impl;
using com.example.spacebattle.utils;
namespace com.example.spacebattle.controller
{
class StartGameCommand : EventCommand
{
[Inject]
public ITimer gameTimer{get;set;}
override public void Execute()
{
gameTimer.start();
dispatcher.dispatch(GameEvent.STARTED);
}
}
}
using strange.extensions.command.impl;
using com.example.spacebattle.service;
namespace com.example.spacebattle.controller
{
class PostScoreCommand : EventCommand
{
[Inject]
IServer gameServer{get;set;}
override public void Execute()
{
Retain();
int score = (int)evt.data;
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();
}
}
}
你调用了Retain该命名保持在内存中,如果你没有调用release可能会造成内存泄漏。
commandBinder.Bind(ServerEvent.POST_SCORE).To();
commandBinder.Bind(GameEvent.HIT).To().To();
commandBinder.Unbind(ServerEvent.POST_SCORE);
commandBinder.Bind(GameEvent.HIT).To().Once();
使用Once()声明可以保证在下次调用之前销毁这个命令
commandBinder.Bind(GameEvent.HIT).InSequence()
.To()
.To()
.To();
请注意Strange目前支持事件或信号映射到命令,但不是两个同时一起映射。
Signal一种调度机制- EventDispatcher 的替代品。
Signal signalDispatchesInt = new Signal();
Signal signalDispatchesString = new Signal();
signalDispatchesInt.AddListener(callbackInt);//Add a callback with an int parameter
signalDispatchesString.AddListener(callbackString);//Add a callback with a string parameter
signalDispatchesInt.Dispatch(42);//dispatch an int
signalDispatchesString.Dispatch("Ender Wiggin");//dispatch a string
void callbackInt(int value)
{
//Do something with this int
}
void callbackString(string value)
{
//Do something with this string
}
//You can do this...
Signal signal = new Signal();
signal.Dispatch(instanceOfASubclass);
//...but never this
Signal signal = new Signal();
signal.Dispatch(instanceOfASuperclass);
//works
Signal signal0 = new Signal();
//works
Signal signal1 = new Signal();
//works
Signal signal2 = new Signal();
//works
Signal signal3 = new Signal();
//works
Signal signal4 = new Signal();
//FAILS!!!! Too many params.
Signal signal5 = new Signal();
using System;
using UnityEngine;
using strange.extensions.signal.impl;
namespace mynamespace
{
//We're typing this Signal's payloads to MonoBehaviour and int
public class ShipDestroyedSignal : Signal
{
}
}
protected override void addCoreComponents()
{
base.addCoreComponents();
injectionBinder.Unbind();
injectionBinder.Bind().To().ToSingleton();
}
commandBinder.Bind().To();
[Inject]
public ShipDestroyedSignal shipDestroyedSignal{get; set;}
//绑定Signal来启动上下文
commandBinder.Bind().To();
//ShipMediator中我们注入Signal然后调用它
[Inject]
public ShipDestroyedSignal shipDestroyedSignal{get; set;}
private int basePointValue; //imagining that the Mediator holds a value for this ship
//Something happened that resulted in destruction
private void OnShipDestroyed()
{
shipDestroyedSignal.Dispatch(view, basePointValue);
}
//通过Signal的Dispatching来调用ShipDestroyedCommand
using System;
using strange.extensions.command.impl;
using UnityEngine;
namespace mynamespace
{
//Note how we extend Command, not EventCommand
public class ShipDestroyedCommand : Command
{
[Inject]
public MonoBehaviour view{ get; set;}
[Inject]
public int basePointValue{ get; set;}
public override void Execute ()
{
//Do unspeakable things to the destroyed ship
}
}
}
override public void Launch()
{
base.Launch();
//Make sure you've mapped this to a StartCommand!
StartSignal startSignal= (StartSignal)injectionBinder.GetInstance();
startSignal.Dispatch();
}
injectionBinder.Bind().ToSingleton();
建议您的视图中包含至少两个不同的组件对象:View and Mediator.
using Strange.extensions.mediation.impl;
using com.example.spacebattle.events;
using com.example.spacebattle.model;
namespace com.example.spacebattle.view
{
class DashboardMediator : EventMediator
{
[Inject]
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);
}
}
}
mediationBinder.Bind().To();