`
wangchuang1113
  • 浏览: 7237 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

robotlegs 全面解读(一)

 
阅读更多
robotlegs    全面解读(一)
                                       —基于元数据的依赖注入

简介:这片教程将和大家一起学习robotlegs的最大特性—依赖注入。通过本篇文章你将会了解,swifsuspender框架是如果基于元数据进行依赖注入的。本文章将结合实例,以最通俗的语言给大家讲解。

首先我们先来理解几个词汇:

其实有时候我们不需要知道这些专业词汇的概念性定义,我只需要知道他在哪里、起了什么作用就行了。

依赖:例如在A类里边,你需要用到b对象的某属性,那么你需要在A类里边做b的引用;
 
Class A 
{
public  var b:B;
} 


这个时候我们就说A就依赖于b,或说b是A的依赖。


注入:还是刚才的A、b为例,刚才我们在A类声明了b但是并没有赋值。这个时候我们在C类里声明a实例,并对其变量赋值;

Class C
{
public  var a:A = new A();
public var b:B=new B();
public function C():void
{
 a. b= b;  //==== 
}
} 


a. b= b;  这个赋值过程我们就叫注入。

元数据:我想这个东西大家应该也都用过,比如我们在Main类前边加的 【swf  】,它可以用来指定舞台大小及帧频。这种方式其实就在给Main类添加元数据,这个[swf]我们叫它元数据标签。除【swf】之外flash内置的标签还有,用来导入外边资源的【Embed】、添加事件处理函数接口的【Event】等,在我们给类添加了这些元数据标签之后, flashplayer运行的时候就会做相应处理。
以上是flash内置的元数据标签,那么我们能不能自定义标签呢,答案是肯定的。其实我们可以在自己的类里边随意添加自定义的标签,它是不会影响类的正常运行。看下例:

//我们建立这样一个类:
//然后在其属性前添加元数据

package {
   public class MyClass extends Object{
      
      [MyMatedata(name="value1",name2="value2")]
      public var a:String;
      public function MyClass(){
        super();
      }
      public function getA():void{
        trace("dd");
      }
   }
} 


其中[MyMatedata(name="value1",name2="value2")]就是我们随便加的一个标签。那这个标签加在这会有什么用呢?

我们看一个as3的公共方法describeType(value:*):XML 通过此方法我们可以得到对象的XML表示。

package {
   public class Main extends Sprite
   {
      public function Main (){
        super();
        var myXml:XML= describeType(new MyClass())
        
        trace(myXml); //打印XML对象
      }
   }
} 


//我们将得到日志:
1 <type name="MyClass" base="Object" isDynamic="false" isFinal="false" isStatic="false">
    <extendsClass type="Object"/>
    <variable name="a" type="String">
      <metadata name="MyMatedata">---------------------------------->自定义元数据
        <arg key="name" value="ha"/>
        <arg key="name2" value="haha2"/>
      </metadata>
      <metadata name="__go_to_definition_help">
        <arg key="pos" value="108"/>
     </metadata>
   </variable>
   <method name="getA" declaredBy="MyClass" returnType="void">
     <metadata name="__go_to_definition_help">
      <arg key="pos" value="189"/>
     </metadata>
   </method>
   <metadata name="__go_to_ctor_definition_help">
     <arg key="pos" value="137"/>
  </metadata>
  <metadata name="__go_to_definition_help">
     <arg key="pos" value="26"/>
   </metadata>
 </type>  
 


Variable:为属性标签
Method:为方法标签
Metadata:为元数据标签

我们可以在<variable name="a" type="String">标签里边看到我们添加的元数据:

<metadata name="MyMatedata">
       <arg key="name" value="ha"/>
        <arg key="name2" value="haha2"/>
     </metadata>




到这里大家应该明白了,其实元数据就是在我们的类里边加一些标记。这样我们就可以根据这些标记对这个对象做一些操作,比如注入。通过解读对象的元数据来进行的注入就是基于元数据的依赖注入了。

下边是我做的一个例子,比较简单,它和swifsuspender框架一样都实现了基于元数据的依
赖注入。

//Injector  为注入器,我只实现了属性注入,较框架里的注入器要简单,易于大家理解。
package org
{
   import flash.utils.Dictionary;
   import flash.utils.describeType;
   import flash.utils.getQualifiedClassName;
   
   public class Injector
   {
      /**
       *储存所有映射的字典,key为[class+#+name],value为Class或Class的实例 
       */
      private  var  m_mappings:Dictionary;
      /**
       * 储存注入描述的字典
       */
      private var m_injectteeDescriptions:Dictionary;
      
      public function Injector(xmlConfig : XML = null)
      {
        m_mappings=new Dictionary(true);
        m_injectteeDescriptions=new Dictionary(true);
      }
      
      /**
       * 将类映射到一个对象,这样在请求[class+name]的时候,就会返回指定的对象
       * @param whenAskedFor - 请求的类
       * @param useValue - 请求类时返回的对象
       * @named named - 注入名,对类进一步区分,[whenAskedFor的全名+'#'+named]是映射的key
       * 
       */
public function mapValue(whenAskedFor : Class, useValue : Object, named : String = "") : void
      {
        var requestName:String=getQualifiedClassName(whenAskedFor);//获得类全面
        m_mappings[requestName+"#"+named]=useValue;
      }
      
      /**
       * 向目标注入
       * @param target
       */     
      public function injectInto(target:Object):void
      {  
        var classZ:Class=target.constructor; //得到目标类
        var injectionPoints:Vector.<PropertyInjectionPoint>=m_injectteeDescriptions[classZ];
        
        if(!injectionPoints)
        {
           injectionPoints=getInjectionPoints(classZ); 
        }
        
        for(var i:int=0;i<injectionPoints.length;i++)
        {
           var injectionPoint:PropertyInjectionPoint=injectionPoints[i];
           var response:Object=m_mappings[injectionPoint._propertyType+"#"+injectionPoint._propertyName];
           
           if(response)
           {
              target[injectionPoint._injectionName]=response
           }
        }
      }
      
      /**
 *读取一个类的属性注入点 
       * @param clazz       读取的类
       * @return     Vector.<PropertyInjectionPoint>    所有属性注入点列表
       * 
       */     
      private function getInjectionPoints(clazz:Class):Vector.<PropertyInjectionPoint>
      {
        var description:XML=describeType(clazz); //获取类的XML描述信息。
        var injectionPoints:Vector.<PropertyInjectionPoint>=new Vector.<PropertyInjectionPoint>();
        
        var injectionPoint:PropertyInjectionPoint;// 声明注入点
        var node:XML;
        
        //对于variable结点中metadata的name是Inject的节点,
        for each (node in description.factory.variable.metadata.(@name == 'Inject'))
        {
          injectionPoint = new PropertyInjectionPoint(node);//注入点为PropertyInjectionPoint对象,即属性注入点对象
          injectionPoints.push(injectionPoint);//在注入点队列中添加改注入点
        }
        
      m_injectteeDescriptions[clazz]=injectionPoints;
      return injectionPoints;
      }
}
}
 
/**
 * 【包外类】属性注入点描述类
 * */
final class PropertyInjectionPoint
{
   public var _propertyName : String;  //注入的属性名称
   public var _propertyType : String; //注入点类型
   public var _injectionName : String;//注入名
   
   public function PropertyInjectionPoint(node:XML)
   {
      _propertyName=node.parent().@type.toString();
      _propertyName=node.parent().@name.toString();
      _injectionName=node.arg.attribute("value").toString();
   }
}
 
 
 
//被注入的类AClass
package org
{
   public class AClass
   {
      [Inject]
      public var b:BClass;
      public function AClass()
      {
      }
      
      public function handler():void
      {
        trace(b);
      }
   }
}
//被映射的类BClass
package org
{
   public class BClass
   {
      public var property:String="";
      
      public function BClass()
      {
      }
   }
}
 
 
//文档类
 
package
{
   import flash.display.Sprite;
   
   import org.AClass;
   import org.BClass;
   import org.Injector;
   
   public class Main extends Sprite
   {
      private var injector:Injector=new Injector()
      public function Main()
      {
        var b:BClass=new BClass();
          b.property="property from BClass";
           injector.mapValue(BClass,b);
        
        var a:AClass=new AClass();
        injector.injectInto(a);
        a.handler();
      }
   }
}
 

//声明:此实例只供参考,如有疏漏,欢迎大家批评指出。


作者:王闯
email :wangchuang1113@163.com;

分享到:
评论

相关推荐

    Unity3d Robotlegs Demo

    Unity3d Robotlegs Demo是一个基于Unity3D游戏引擎的示例项目,它展示了Robotlegs框架在实际开发中的应用。Robotlegs是一个广泛使用的MVC(Model-View-Controller)框架,适用于ActionScript 3和JavaScript,但也有...

    RobotLegs演示程序实例

    RobotLegs是一个强大的MVC(模型-视图-控制器)框架,主要应用于ActionScript和AS3编程语言,常用于创建富互联网应用程序(RIA)或Flex和Flash项目。本实例是RobotLegs框架的一个演示程序,名为"RobotLegs演示程序...

    Robotlegs框架的Flex简单实例

    Robotlegs是一款非常流行的ActionScript 3(AS3)和Flex应用程序框架,它提供了一种模块化、可扩展的方式来构建灵活且易于维护的项目。本实例将带您了解如何在Flex环境中使用Robotlegs框架进行开发。 首先,让我们...

    Robotlegs2.2萝卜腿最新入门Demo

    Robotlegs 是一个开源的ActionScript 3和TypeScript的MVC(模型-视图-控制器)框架,它为游戏、应用程序和富互联网应用(RIA)提供了一种灵活和可扩展的架构。萝卜腿,即Robotlegs,因其中文名形象而被广泛称呼。在...

    开源框架Robotlegs

    Robotlegs是一个开源框架,主要用于ActionScript语言的MVCS(Model-View-Controller-Service)架构模式,用于创建Flex和AIR等Adobe Flash平台应用。Robotlegs具备灵活的结构和松耦合的设计,使其成为面向对象编程和...

    robotlegs-framework

    Robotlegs 框架是一个广泛使用的ActionScript 3和AS3开源框架,专门设计用于构建灵活、可扩展的Flash和Flex应用程序。这个框架的核心理念是提供一个强大的MVC(Model-View-Context)架构,帮助开发者组织代码,提高...

    Robotlegs最佳实践

    总结起来,Robotlegs是一个强大的ActionScript 3框架,它利用依赖注入来简化组件之间的通信,并提供了MVCS模式的实现。通过理解并应用这些最佳实践,开发者可以更高效地构建Flash、Flex和AIR应用程序,同时保持代码...

    (Robotlegs五子棋)HelloRobotlegs

    【描述】:这篇博客文章并未提供具体的描述,但根据标题可以推断,它可能是一个关于使用Robotlegs框架开发五子棋游戏的教程或示例项目。Robotlegs是一个流行的ActionScript 3(AS3)框架,用于构建可扩展和模块化的...

    Robotlegs2框架例子

    采用Robotlegs2.2框架做的Flex简单登录例子,AIR项目,FLEX SDK为4.6.0,Flash Builder4.7开发,没有注释,对Robotlegs框架感兴趣的可以看下。

    为框架初学者准备的RobotLegs

    介绍RobotLegs框架,为初学打下好的基础

    robotlegs-sharp-framework, C# 应用程序框架从Robotlegs移植到 ActionScript 3.zip

    robotlegs-sharp-framework, C# 应用程序框架从Robotlegs移植到 ActionScript 3 RobotlegsRobotlegs sharp是 C# 从 Robotlegs移植到 AS3的应用程序框架。 它提供:依赖项注入模块管理命令管理视图管理即插即用扩展你...

    starling_feather_robotlegs

    例如,一个简单的应用场景可能是:使用Robotlegs创建一个游戏主控制器,管理游戏状态;在Starling舞台上创建一个Feather的列表组件,显示游戏中的角色或物品。当用户点击列表项时,Robotlegs会处理点击事件,并通过...

    ActionScript Developers Guide to Robotlegs

    《ActionScript开发者指南至Robotlegs》一书由Joel Hooks和Stray(Lindsey Fallow)撰写,出版于2011年,是针对ActionScript开发者深入理解并运用Robotlegs框架的一部详尽指南。Robotlegs是一款轻量级的ActionScript...

    robotlegs guide for actionscript developers source code

    Robotlegs 框架是基于ActionScript 3.0的一款著名的应用程序框架,它为游戏、富互联网应用程序(RIA)和其他基于Flash平台的项目提供了强大的架构支持。此资源"robotlegs guide for actionscript developers source ...

    ActionScript_Developers_Guide_to_Robotlegs

    《ActionScript开发者指南到Robotlegs》是一本针对ActionScript开发者介绍如何使用Robotlegs框架的书籍。本书由Joel Hooks和Stray(Lindsey Fallow)合著,并于2011年由O'Reilly Media, Inc.出版。该书系统地介绍了...

    robotlegs-framework-v1.5.2.zip

    总结来说,Robotlegs框架v1.5.2是一个强大的工具,尤其适合Flex应用的开发。通过提供的各种文件,开发者可以快速上手,实现高效、结构化的编程,同时享受到MVC模式带来的好处。无论是初学者还是经验丰富的开发者,都...

Global site tag (gtag.js) - Google Analytics