Circular References from IsDirty

Circular References from IsDirty

Old forum URL: forums.lhotka.net/forums/t/6028.aspx


Jack posted on Friday, December 19, 2008

I'm running into the StackOverflowException from having a circular reference of managed properties.  I thought the solution was a simple use of the [NonSerialized] and [NotUndoable] but that doesn't seem to be the case and I'm wondering if it is because of something I am misunderstanding in the FieldManager.

ParentBO
    ChildListBO1
        ChildBO1
    ChildListBO2
        ChildBO2
    ChildListBO3
        ChildBO3
             LinkedParentBO

As soon as I introduce the ChildBO3.linkToParent(ParentBO) I get the circular reference.

I have the LinkedParentBO defined with both [NonSerialized] and [NotUndoable] but that doesn't seem to matter.

[NonSerialized()]
        [NotUndoable()]
        private static PropertyInfo<ParentBO> LinkedParentBOProperty = RegisterProperty<ParentBO>(typeof(ParentBO), new PropertyInfo<ParentBO>("LinkedParentBO"));
       
I create the circular reference:

        internal void LinkToParent(LinkedParentBO parent)
        {
            LoadProperty<ParentBO>(LinkedParentBOProperty, parent);
        }

I can see in the BeginEdit how it filters out the [NotUndoable] Fields but I don't see how in the FieldManager.IsDirty() that it does?

When I look at the call stack there is definitely the circular reference loop happening.

I must be missing something obvious.

thanks

jack

Jack replied on Friday, December 19, 2008

I've gotten around the issue by implementing a GetMyParent( ) approach as per http://forums.lhotka.net/forums/thread/24850.aspx but I still want to understand why the earlier approach didn't work.

Thanks

jack

ajj3085 replied on Friday, December 19, 2008

Hi,

The NonSerialized and NotUndoable should be placed on your property backing field, not the PropertyInfo field...

So declare:
[NonSerialized, NotUndoable]
private ParentBO _parent;

Your load should be:
        internal void LinkToParent(LinkedParentBO parent)
        {
            _parent = parent;
        }

Then if you have a getter:
internal ParentBO ParentBO { get ReadProperty(  LinkedParentBO, _parent ); }

HTH

Jack replied on Friday, December 19, 2008

Is that because they won't work on a managed backing field?

I think I know prefer the GetParent idea then - saves me having to reconnect after serialization etc.

Thanks

ajj3085 replied on Friday, December 19, 2008

Well, I think it's the way the compiler works.  You're applying those attributes to the static field that hold the PropertyInfo... it's not applying them to the value.  It has no way of knowing where the value will be stored, so there's no way the compiler could do that.

I haven't read the book yet (it shipped today though!!), but I haven't found anyway to apply those attributes to the field without going the managed property / unmanaged field route.

Copyright (c) Marimer LLC