Small bug

Jan 22, 2014 at 4:31 PM

I'm using your library for a WP8 project and I've found a small bug that only appears under a very specific circumstance.

I'm using mvvmlight, by the way.

Imagine an abstract viewmodel class A. Now you have two classes that inherit from class A, let's call them B and C. There are properties that need to be persisted on A, B and C.

Now you have a property on MainViewModel of type A, that can be either B or C on runtime. When the application is tombstoned it throws a catched exception on PersistenceStorage.StoreObjectToIsolated because B and C aren't on KnownTypes. This produces an empty PersistanceProperties file, which in turn produces a crash when activating the application.

The root of the problem is on KnownTypes.GetKnownTypes, it doesn't get the types B and C due to not having a property directly of those types.

For now I can fix it by having two persisted dummy properties of types B and C but I thought you should know. Maybe a way to directly add a type would be a good idea.

By the way, I've taken a look at the generated PersistanceProperties file and all properties inside a persisted object are stored in the xml, not only the ones marked with the Persist attribute, are you aware of that?
Jan 22, 2014 at 5:06 PM

The persistence manager should harvest properties marked with the Persist attribute at vm root level, it doesn't look inside property objects for the attribute, is this what you mean?

With the GetKnownTypes issue, you might want to manually load the types into KnownTypes instead. There's nothing that can be done about this as the XmlSerializer needs to know the types.


Jan 23, 2014 at 8:33 AM

No, that's not what I mean. In my previous example, I had a property of type A, which is harvested, but in really have objects of type B or C - which inherit from A - and those types aren't harvested. I guess you could harvest every single inheritance from type A, but I don't think that's a good idea (you could have a property of type object...).

Maybe the optimal solution would be to have a class attribute that means "harvest this type even if you don't find a persisted property with it".

Meanwhile, I've added this method to PersistenceManager and it suits my needs:
        /// <summary>
        /// Needed to add types not collected on KnownTypes.GetKnownTypes but needed later due to inheritance.
        /// </summary>
        /// <param name="newTypes">New types to add.</param>
        public void AddKnownTypes(Type[] newTypes)
            Type[] oldTypes = PersistenceStorage.KnownTypes;
            PersistenceStorage.KnownTypes = new Type[oldTypes.Length + newTypes.Length];
            oldTypes.CopyTo(PersistenceStorage.KnownTypes, 0);
            newTypes.CopyTo(PersistenceStorage.KnownTypes, oldTypes.Length);
Wait, were you talking about my last sentence with your question? I was just talking about the generated xml file itself, I can see properties NOT marked with the Persist attribute there. This doesn't introduce any bug, it just makes the file bigger than needed.

Jan 23, 2014 at 9:03 AM
Sorry, I replied in the wrong order. Your solution for know types seems sensible to me.

When I was talking about harvesting properties I was talking about the xml file. It should only harvest properties marked with Persist in the root of a registered VM and does not take notice of this attribute inside objects. To remove unwanted properties from these objects, just use [XmlIgnore] attribute.
Jan 23, 2014 at 10:05 AM
Yeah, I see it. Thanks!