• 热门专题

认识Robotlegs(三)RL内置的注入机制

作者:kevin褚华  发布日期:2014-06-13 19:51:17
Tag标签:机制  
  •   Robotlegs中的注入是由注入器Injector实现,先来看看Robotlegs中哪些地方存在注入器Injector。

      首先Context里面有Injector,CommandMap、MediatorMap和ViewMap里面也有Injector。

      Context自身内部除了有一个Injector单例之外还有CommandMap、MediatorMap、ViewMap这些单例,这些对象内部具有Injector。Robotlegs框架内部存在Injector的类基本上就是这4个,当然除了Context内部的commandMap、mediatorMap、viewMap单例之外你也可以手动创建新的CommandMap、MediatorMap、ViewMap,本文不讨论这种情况,我们在此只分析Robotlegs内置结构的4种Injector和它们的注入机制,后面提到的CommandMap、MediatorMap、ViewMap皆是指Context.commandMap、Context.mediatorMap和Context.viewMap。

      Context,CommandMap,MediatorMap,ViewMap内部都有Injector,但它们是不同的。CommandMap.injector和MediatorMap.injector是Context.injector的子注入器,它们都继承了Context.injector的注入规则,同时又拥有各自的注入规则。而ViewMap.injector使用的就是Context.injector,也就是说ViewMap和Context的注入器是同一个。

      Robotlegs区别与其他mvc框架的特色是运用了命令模式和中介模式规范了注入机制的使用,从而使整个应用程序框架结构更清晰高效易于维护。下面我们具体来分析一下这些注入机制。

    Context相关的注入机制    

      Context中的Injector就是注入器的一般用法,Context在初始化的时候内部的添加了下面这些注入规则:

        injector.mapValue(IReflector, reflector);
        injector.mapValue(IInjector, injector);
        injector.mapValue(IEventDispatcher, eventDispatcher);
        injector.mapValue(DisplayObjectContainer, contextView);
        injector.mapValue(ICommandMap, commandMap);
        injector.mapValue(IMediatorMap, mediatorMap);
        injector.mapValue(IViewMap, viewMap);
        injector.mapClass(IEventMap, EventMap);

      被Context.Injector(或者子注入器)注入过的类内部都可以接收这些注入规则。注意这里的EventMap不是对象实例,每个IEventMap请求都会得到一个新的EventMap对象。此外,经过ViewMap映射的显示对象也可以接收这些注入规则,本文ViewMap相关的注入机制中会介绍。

    CommandMap相关的注入机制     

      CommandMap内部的Injector是Context.Injector的子注入器。调用CommandMap.mapEvent方法时需传入(eventType:String, commandClass:Class, eventClass:Class = null)这些参数,CommandMap为总线eventDispatcher添加名为eventType的事件侦听。 当总线eventDispatcher派发名为eventType的事件时CommandMap执行了如下代码:

        injector.mapValue(Event, event);//这里Event是flash.events.Event 或者是eventClass类型,event是总线eventDispatcher派发的事件。
        var command:Object = injector.instantiate(commandClass);
        command.execute(); 


      总线eventDispatcher接收到事件时Robotlegs会创建commandClass对象实例,同时把event注入到了commandClass,如果commandClass内部需要接收这个注入只要加入如下代码:

        [Inject]
        public var event:Event;    //也可以把Event换成eventDispatcher派发的具体事件类型eventClass。

      前面说过CommandMap.Injector是Context.Injector的子注入器,所以CommandMap.Injector把自身的注入规则注入到commandClass的同时也会把Context.Injector的注入规则注入进commandClass。事实上commandClass的基类Command已经为我们定义了下面这些注入点,我们在commandClass内部可以直接使用这些注入。

        [Inject]
        public var contextView:DisplayObjectContainer;
        [Inject]
        public var commandMap:ICommandMap;
        [Inject]
        public var eventDispatcher:IEventDispatcher;
        [Inject]
        public var injector:IInjector;
        [Inject]
        public var mediatorMap:IMediatorMap;

    MediatorMap相关的注入机制

        MediatorMap内部的Injector是Context.Injector的子注入器。调用MediatorMap.mapView方法时需传入(viewClass:*, mediatorClass:Class, injectViewAs:* = null)这些参数,MediatorMap为contextView添加Event.ADDED_TO_STAGE事件,viewClasss实例为显示对象且必须为contextView的子显示对象。当viewComponent显示对象创建并添加到Stage的时候MediatorMap执行了如下代码:

        var mediator:IMediator;
        injector.mapValue(viewClass, viewComponent);
        mediator = injector.instantiate(mediatorClass);
        mediator.onRegister();

         所以Robotlegs在创建mediatorClass对象实例的同时把viewComponent注入到了mediatorClass,如果mediatorClass内部需要接收这个注入只要加入如下代码:

        [Inject]
        public var view:viewComponent;

      在mediatorClass的onRegister方法内部可以访问到注入的view。 另外要注意的是一个mediator可以对应多个view,MediatorMap.mapView方法有injectViewAs这个参数,它可以是一个viewClass组成的数组,如果是这种情况injector会为每一个viewClass都创建注入规则,这样在mediatorClass内部可以接收多个viewClass注入。 当injectViewAs参数非空的时候会忽略viewClass参数。

      同样,前面说过MediatorMap.Injector是Context.Injector的子注入器,所以MediatorMap.Injector把自身的注入规则注入到mediatorClass的同时也会把Context.Injector的注入规则注入进mediatorClass。事实上mediatorClass的基类Mediator已经为我们定义了下面这些注入点,我们在mediatorClass内部可以直接使用这些注入。

        [Inject]
        public var contextView:DisplayObjectContainer;
        [Inject]
        public var mediatorMap:IMediatorMap;

    ViewMap相关的注入机制

       ViewMap可以添加显示对象(DisplayObject的子对象),经过ViewMap.mapType添加的显示对象第一次被放置到舞台的时候会被注入Context.injector的注入规则,在这些对象内部可以添加注入点来接收Context.injector的注入。当显示对象添加到舞台时ViewMap执行了如下代码:     injector.injectInto(target);

      这里的injector就是Context.injector,target是被ViewMap.mapType添加过的显示对象。target可以接收的注入规则可以参考上面的Context相关的注入机制。     此外ViewMap还有一个ViewMap.mapPackage方法用来添加类名前缀,如果被放置到舞台的显示对象的类名符合这些前缀同样也会被注入Context.injector的注入规则。

    KevinChu

    2014-6-11

延伸阅读:

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规