3 Replies Latest reply on Oct 24, 2007 6:25 PM by Ansury

    Reflection in Flex is it really usefull?

    levancho Level 3
      I am standing against a brick wall, so yet again I am trying to see if there is any way out of it, proble is with dynamically creating classes issue in Flex, it seems that there is either something fundamentally not possible or its planned to be done in future versions, I am talking about our old friend getDefinitionByName(),
      here is my issue and maybe someone can suggest some workaround for it,
      I have two classes : DefaultSecurityManager Implements ISecurityManager and
      CustomSecurityManager implements ISecurityManager now since they both implement ISecurityManager , I can do following without any problem .



      public var mySecurityManager:ISecurityManager = new DefaultSecurityManager ();
      and then I can also do :
      mySecurityManager = new CustomSecurityManager ();
      so far no problem at all now things get hairy when I want to do all this dynamically,

      for example if I have configuration xml that has node in it : <security manager="my.package.DefaultSecurityManager" >

      now I don't really know at runtime what value will be for manager="my.package.DefaultSecurityManager" it can just as easily be manager="my.package.CustomSecurityManager" all I care that they both implement ISecurityManager , and thats because I am doing following inside init Method :

      var aClassString:String = securityXMLNoode.@manager; // this gives me "my.package.DefaultSecurityManager" or "my.package.CustomSecurityManager" as a string. so far so good.

      now I know there is shortcoming in flex with dynamically creating classes issue with having the variable imported before creating that class, so that is ok, I can still work myself around it(theoretically), what if I do this on top of the class

      public var mySecurityManager:ISecurityManager;

      and then :

      var aClassString:String = securityXMLNoode.@manager;
      var ClassRef:Class = getDefinitionByName(aClassString) as Class;
      mySecurityManager = new ClassRef() as ISecurityManager; // this does not work.even if there is no justifiable reason for it, DefaultSecurityManage is type ISecurityManager and I have variable of type ISecurityManager defined and imported.

      this problem basically makes reflection in flex completely unusable, and I cant seem to find a way around to get class created dynamically and not have to define the concret classe's dataType as variable (because I dont really know it at right time all I know it is that its type ISecurityManager).

      does anyone have any idea for workaround?
      please, please

        • 1. Re: Reflection in Flex is it really usefull?
          Ansury Level 3
          If I understand what you're saying, I ran into the same issue once, and I'll agree that it's pretty annoying. Java handles this stuff much better. It seems that we should be able to make the cast you're doing using "as".

          I think the annoying workaround I had to use was to abandon reflection and just conditionally create different types of objects based on a string stored on the Object I was working with.

          I'm working with "Objects" with attributes set on them. ex.
          Object["attribute"] = someValue;

          So I think I'm doing this unless I'm delusional and recalling incorrectly...

          if (Object["type"] == "SomeType") {
          typeObj = new SomeType();
          typeObj.attrib = Object["attrib"];
          } else if (Object["type"] == "SomeOtherType") {
          ......
          }

          Which sucks. Could be a switch statement I guess, but that still sucks. I can't remember if I later found a better solution or not, I'll have to check when I'm able later tonight.

          I'd be interested in better solutions to this problem too!
          • 2. Re: Reflection in Flex is it really usefull?
            levancho Level 3
            it is a seriouse blocker.
            • 3. Reflection in Flex is it really usefull?
              Ansury Level 3
              Okay... my memory was wrong. What I'm doing is actually much fancier, and nearly "automatic". ....And I did use reflection. But I don't think it's going to help you-- I didn't need to cast to a common interface.

              You would think that you should be able to do this:

              var classRef:Class = getDefinitionByName("Test") as Class;
              var testObj:Object = new classRef();
              var test:ITest = testObj as ITest;
              trace(testObj);

              With a breakpoint set on the trace() line, I can see that testObj is indeed a "Test" object, but "test" (3rd line) is null after trying to cast to an interface that should be compatible with Test. (Test implements ITest)

              Of course, you CAN do this cast:

              var t2:Test = testObj as Test;

              I wouldn't say it's a matter of crappy reflection... it seems to be a matter of crappy casting...am I missing something here?
              I also tried extending a class instead of implementing an interface - same result.

              var classRef:Class = getDefinitionByName("Test") as Class;
              var testObj:Object = new classRef();
              var test:Test = testObj as Test;
              var t2:Test2 = testObj as Test2; //Null

              If Test extends Test2, by the rules of inheritance Test "is-a" Test2 -- so why can't we cast to it?