How can I MarkNew the whole object graph during a DataPortal_Update?

How can I MarkNew the whole object graph during a DataPortal_Update?

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


j0552 posted on Thursday, July 05, 2012

Hi

I have a large object graph. There is a situation where, depending on the the status of the root object, I would like to mark the whole object graph as new when an update is called. e.g.

protected override void DataPortal_Update()
{
    if (SaveAction == SaveAction.Draft){
        //Mark everything as new.
   
}
}

Is there an elegant way to handle this? What are my options?

Thanks
Andrew

 

TSF replied on Thursday, July 05, 2012

From Rocky's e-book:

The MarkNew method is a protected method of BusinessBase, and you can call this method to mark an object as being new. You should not normally need to directly call MarkNew, because it is invoked automatically in most cases.

Also stated in his e-book, by default, calling MarkNew also invokes MarkDirty.  So if you don't want that to happen, you'll need to override the MarkNew method and then call MarkClean to make sure the object isn't marked as dirty.

[Edit]  I just realized you were asking about marking all child objects as new, so I'm not sure if the MarkNew method on the root takes care of that on the children.  I guess since you're asking, perhaps it doesn't.

JonnyBee replied on Thursday, July 05, 2012

no,

this is not possible inside DatapPortal_XYZ as the datapotal will help you to maintain proper state. 

IE: The DataPortal will call MarkOld after DataPortal_Update is completed. 

j0552 replied on Thursday, July 05, 2012

OK, so the best thing I have come up with is:

1. Override save
2. after validation but before transfer to the DataPortal, go though the root and all children and call MarkNew()

I have to derive all the children from a custom BusinessBase which gives me an internal MarkNew(), e.g.:

internal new void  MarkNew()
{
    
base.MarkNew();
}

Does this sound reasonable? What should the overridden Save method look like? Or is there a BB method which sits between Save and the DataPortal I can use?

Andrew

JonnyBee replied on Thursday, July 05, 2012

Have you consiered a switchto ObjectFsctories. In object fatories the DataPortal will not help you with state management and you could call MarkNew in the Update method? 

I'm not sure why you need to call MarkNew in the DataPortal_Update metod.
Could this just be part of your persistance logic in the DataPortal_Update? 

j0552 replied on Friday, July 06, 2012

I'm not sure I can just treat this all as persistence logic. Likewise I can't see how using ObjectFactories can help, although I haven't had to use them yet.

I've attached a diagram to illustrate the workflow I require.

 

Depending on the Status and the choice of 'Save' or 'Publish' we need to

decide whether to over-write the original object, or whether to create a new

linked copy (which will eventually over-write the original when it is

published).

 

I just need to know the best way to do this using business objects. I hope you can help point me in the right direction.

 

Thanks

Andrew

JonnyBee replied on Saturday, July 07, 2012

Hi,

One of the key issues is to identify what happens on the client versus the server and what should be handled as "persistence logic".'

Is there f.ex different rules  based on the IsNew/Old to be enforced before Save? 

One option is to create command objects to do the persistence logic and send the "Root" object as parameter. (This would also allow you to change the metastate of the object tree to IsNew in the serverside update).

Using the DataPortal_XYZ methods the DataPortal_XYZ are "member" calls and the DataPortal will help you maintain the correct state. IE The DataPortal will create the object - call the XYZ method and then set the correct state.

ObjectFactories are external classes that must create the objects, load data and set the metastate - then return the object to the client. This gives a little more flexibility but also adds complexity in that your code must maintain the state.

Using ObjectFactories will f.ex allow you to return a new instance of the BO from a Save - wheres DataPortal_XYZ is an instance method an cannot return another object.

j0552 replied on Monday, July 09, 2012

Hi Jonny

 

I think my specification requires behaviour modification rather than just changes to data, i.e. this is business logic not persistence logic. Therefore I need to do everything client side. I’ve created a new method based on the CSLA Save method. Basically I do all modifications to the object tree before it’s passed to the DataPortal.Update method.

 

        private StandardPublication SaveInternal()

        {

            StandardPublication local;

            // Do validation, busy tests etc.

            if (IsDirty)

            {

                if (!IsLinkedCopy && SaveAction == SaveAction.Save)

                {

                    // create a new linked copy

                    StandardPublication copy = CreateLinkedCopy(this);

                    local = DataPortal.Update(copy);

                }

                else if (IsLinkedCopy && SaveAction == SaveAction.Publish)

                {

                    // merge linked copy into the original and delete linked copy

                    StandardPublication orig = MergeLinkedCopy(this);

                    local = DataPortal.Update(orig);

                }

                else

                {

                    local = DataPortal.Update(this);

                }

            }

            else

            {

                local = this;

            }

            OnSaved(local, null, null);

            return local;

        }

 

The advantages are that nothing needs doing server-side, the business logic is contained, i.e. only need to change one method in the root BusinessBase class.  The only pain I can see at the moment is mapping the whole object graph to the new one and again when merging the linked version back to the original one. I have to be careful about how I create the new object tree. It has to be created in a similar way to how an object is created in the UI, rules must run in correct order.

 

Can you tell me if you see a problem with this approach in general? It looks promising so far.

 

Thank you

Andrew

 

Copyright (c) Marimer LLC