You will sooner or later need a Deep Clone

Pretty often you have user scenarios that require you to copy an existing object structure. Like when handling revisions of things and the user wants a new revision but want to start with the old and just tweak a few values.

In cases like these it would be neat with a clone mechanism of your modeled objects. And once you have a clone mechanism you pretty soon will discover that cloning just one object will not suffice – you want to follow associations and clone owned child objects – but only in some cases – in other cases you don’t want to clone the child objects but rather reference the same ones from the clone.

So – how can we help? How about letting a viewmodel act as a definition for what the clone should do? How about this:

image

Given the model above and a ViewModel below:

image

You can do things like this:

PersistenceEcoSpace es = new PersistenceEcoSpace(this);
ClearEcoSpace(es);
es.Active = true;
Person persontoclone = new Person(es);
persontoclone.FirstName = "A";
persontoclone.LastName = "B";
persontoclone.DateOfBirth = DateTime.Now;
Person clonedPerson=
            Eco.ViewModel.Runtime.ViewModelAidedObjectDeepClone.Clone(
                           es, persontoclone, "ViewModel_Person_DeepClone").GetValue<Person>();
Assert.AreEqual(persontoclone.FirstName, clonedPerson.FirstName);
Assert.AreEqual(persontoclone.LastName, clonedPerson.LastName);
Assert.AreEqual(persontoclone.DateOfBirth, clonedPerson.DateOfBirth);

And since the ViewModel defines our scope – or how deep our clone will go – this is also valid:

Person persontoclone = new Person(es);
persontoclone.FirstName = "A";
persontoclone.LastName = "B";
persontoclone.DateOfBirth = DateTime.Now;
persontoclone.OwnedBuildings.Add(new Building(es) { Address = "c", ZipCode = 123 });
persontoclone.OwnedBuildings.Add(new Building(es) { Address = "d", ZipCode = 456 });
persontoclone.Home=new Residential_Building(es) { Address = "d", ZipCode = 456,TotalRent=1.23 };

Person clonedPerson2 = 
       Eco.ViewModel.Runtime.ViewModelAidedObjectDeepClone.Clone(
               es, persontoclone, "ViewModel_Person_DeepClone").GetValue<Person>();
Assert.AreEqual(persontoclone.FirstName, clonedPerson2.FirstName);
Assert.AreEqual(persontoclone.LastName, clonedPerson2.LastName);
Assert.AreEqual(persontoclone.DateOfBirth, clonedPerson2.DateOfBirth);
Assert.AreEqual(persontoclone.OwnedBuildings[0].Address,clonedPerson2.OwnedBuildings[0].Address);
Assert.AreEqual(persontoclone.OwnedBuildings[1].Address,clonedPerson2.OwnedBuildings[1].Address);
Assert.AreNotSame(persontoclone.OwnedBuildings[1],clonedPerson2.OwnedBuildings[1]);
Assert.AreNotSame(persontoclone.Home,clonedPerson2.Home);
Assert.AreEqual(persontoclone.Home.Address, clonedPerson2.Home.Address);
This entry was posted in CO-Unique, Declarative, SourceCode, ViewModel. Bookmark the permalink.

One Response to You will sooner or later need a Deep Clone

  1. Denard John says:

    Hi
    Can you help me I can’t get the attribute ViewModelAidedObjectDeepClone from Eco.ViewModel.Runtime
    What am I making wrong?

Leave a Reply

Your email address will not be published. Required fields are marked *

*