# Complex objects graph

We briefly introduced [MementoEntity and MementoEntityCollection](/memento/change-tracking-service/memento-entities.md) and we've seen how to [track changes in a simple graph](/memento/change-tracking-service/handling-change-tracking/simple-model.md) and in [collections](/memento/change-tracking-service/handling-change-tracking/collections.md).

The last type of graph we want to be able to track is a complex graph, where at least one of the properties of the root tracked object is a memento entity or a memento collection itself:

```csharp
class Person : MementoEntity
{
    public Person()
    {
        this.Addresses = new MementoEntityCollection<Address>();
    }

    public String FirstName
    {
        get { return this.GetPropertyValue(() => this.FirstName); }
        set { this.SetPropertyValue(() => this.FirstName, value); }
    }

    public String LastName
    {
        get { return this.GetPropertyValue(() => this.LastName); }
        set { this.SetPropertyValue(() => this.LastName, value); }
    }
    
    public IList<Address> Addresses { get; private set; }
}

class Address : MementoEntity
{   
    public String Street
    {
        get { return this.GetPropertyValue(() => this.Street); }
        set { this.SetPropertyValue(() => this.Street, value); }
    }
}
```

In the above sample the `Person` class has a property, `Addresses`, whose type is itself a memento entity, a `MementoEntityCollection<Address>` in this specific case. Using the following snippet:

```csharp
var memento = new ChangeTrackingService();

var person = new Person();
memento.Attach( person );
```

the `Addresses` collection is not automatically tracked, the memento does not know anything of the structure of the graph. We can update the `Person` class so to instruct the memento that also the `Addresses` collection needs to be tracked:

```csharp
class Person : MementoEntity
{
    protected override void OnMementoChanged( IChangeTrackingService newMemento, IChangeTrackingService oldMemento )
    {
        base.OnMementoChanged(newMemento, oldMemento);
        if(oldMemento != null) 
        {
            oldMemento.Detach(this.Addresses);
        }
        
        if(newMemento != null) 
        {
            newMemento.Attach(this.Addresses);
        }
        
    //rest of the Person class code
}
```

We are intercepting the moment in which the `Person` instance is tracked by the memento service overriding the `OnMementoChanged` and we are manually propagating the memento to inner instances. It is important to detach the memento entity from the previous memento instance if any, a memento entity can be tracked by one memento only at a time.

NOTE: changes to a `MementoEntityCollection<T>` automatically propagates the memento service to list items if they are a memento entity.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.radicalframework.com/memento/change-tracking-service/handling-change-tracking/complex-graph.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
