Mixing injection with 'registerClassAlias' overrides DI and creates new instance?

seanjamesduffy's Avatar

seanjamesduffy

03 Dec, 2015 01:07 PM

Hi
I'm having an issue when trying to re-assign objects from a SharedObject.
Basic example:
I have a model which I want to save to local storage (SharedObject) then load and re-assign to my app's model when I open the app.
The model (let's call it UserProfileModel) is mapped to the injector in my config class like so:
injector.map(UserProfileModel).asSingleton(true);
However, when I call userProfileModel = sharedObject .data.userProfileModel as UserProfileModel it seems to copy it into a different instance of a userProfileModel (even though this instance has been injected and should be a singleton).

Basically if I inject my UserProfileModel instance into 2 classes and assign it from a SharedObject in one class but try to read it in another they have different property values. One gets updated and not the other. So it looks like there are 2 different instances. Also if I add a trace to the constructor it definitely gets created twice. I think that's due to the registerClassAlias(UserProfileModel, "models.UserProfileModel") but not 100% sure on that.

I only ever want a single instance of this model to be created but also need to use registerClassAlias to assign it.

I have noticed that I can re-assign each property in the injected version rather than doing a pure re-assignment of the object and this works but isn't as clean as just re-assigning it.

i.e. this doesn't work (properties aren't updated in other places the model's injected)
userProfileModel = sharedObject .data.userProfileModel as UserProfileModel

this does work:
userProfileModel.id = sharedObject .data.userProfileModel.id;
userProfileModel.name = sharedObject .data.userProfileModel.name;
etc

I'm guessing that having the 'as UserProfileModel' and registerClassAlias over-rides the DI and creates a new instance of the model only accessible within that classes scope?

Is there any way I can make this work without having to manually assign each property when copying back from disk?

Thanks

  1. Support Staff 1 Posted by Ondina D.F. on 04 Dec, 2015 01:07 PM

    Ondina D.F.'s Avatar

    Hi,

    Also if I add a trace to the constructor it definitely gets created twice. I think that's due to the registerClassAlias(UserProfileModel, "models.UserProfileModel") but not 100% sure on that.

    Yes, that's right, it only gets created twice when a registerClassAlias is used or a metatag like
    [RemoteClass(alias=" UserProfileModel")] inside of UserProfileModel and when there is already some data stored on disk. I just tested your use case: in the flash builder profiler one instance of UserProfileModel holds the values saved on disk and the other instance is the one instantiated by the injector.
    Nevertheless, in my test the UserProfileModel, injected in different other classes as well, gets updated and shows the same values after reading data from the shared object.

    There will be only one instance of your model, if you map the model like shown in this discussion:
    http://knowledge.robotlegs.org/discussions/questions/769-question-a...

    For robotlegs 2 the mapping would look like this:

    var profileModel: UserProfileModel;
    var sharedObject:SharedObject = SharedObject.getLocal("application-name");
    injector.map(SharedObject).toValue(sharedObject);       
    if (sharedObject.data.profileModel != null)
    {
        profileModel = sharedObject.data.profileModel;
        injector.map(UserProfileModel).toValue(profileModel);
    }
    else
    {
        injector.map(UserProfileModel).asSingleton();
    }
    

    It works well on my end.

    Another way of solving this would be to use some kind of object introspection (ObjectUtil, describeType, as3commons-reflect)
    to set model's data without having to know each property's name Or, you could use JSON to stringify(sharedObject.data) and then parse it inside your model's method to set its properties. That works well for private properties as well.

    Also, I'm mentioning the IExternalizable as a possible solution to a use case like yours. I never used it, so I can't say much about it.

    Hope that helps.

    Ondina

  2. 2 Posted by Sean Duffy on 04 Dec, 2015 06:25 PM

    Sean Duffy's Avatar

    That helps loads Ondina!
    I have set it up as in your example above and it does indeed work without
    creating multiple instances of the model.
    It means I can re-assign my object using registerClassAlias, though it's
    probably best practise to use object introspection (especially for nested
    objects) but this certainly solves this problem for me.
    Thanks you guys for all the work on RobotLegs btw, I've not posted on here
    for ages but myself and a colleague have used it on several AIR x-platform
    mobile apps and it's been really useful at organising the app's
    architecture. The above method of mapping the model with the disk data will
    help get things cleaner too.

    Cheers
    Sean

  3. 3 Posted by seanjamesduffy on 04 Dec, 2015 06:26 PM

    seanjamesduffy's Avatar

    That helps loads Ondina!
    I have set it up as in your example above and it does indeed work without creating multiple instances of the model.
    It means I can re-assign my object using registerClassAlias, though it's probably best practise to use object introspection (especially for nested objects) but this certainly solves this problem for me.
    Thanks you guys for all the work on RobotLegs btw, I've not posted on here for ages but myself and a colleague have used it on several AIR x-platform mobile apps and it's been really useful at organising the app's architecture. The above method of mapping the model with the disk data will help get things cleaner too.

    Cheers
    Sean

  4. Support Staff 4 Posted by Ondina D.F. on 05 Dec, 2015 06:26 PM

    Ondina D.F.'s Avatar

    Hey Sean,

    I'm glad to hear that the mapping-example solved your problem and also that you and your colleagues are enjoying using robotlegs:)

    I'm marking this discussion as resolved (closing it), but feel free to re-open it or to create new discussions for other questions, if need be.

    See you!
    Ondina

  5. Ondina D.F. closed this discussion on 05 Dec, 2015 06:27 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac