In CSLA 3.5 Rocky introduced to us for the first time the child data portal. This is a significant change in how we manage child objects in CSLA. To support this shift Rocky leverages the FieldManager object as well as some tricky reflection to ensure that the correct calls to the ChildDataPortal are invoked. Understanding how CSLA determines the proper ChildDataPortal method to invoke is critical for debugging when issues arise with these declarative style operations.
Below is a simple DataPortal_Insert method from a EditableRoot object name Customer. Note the call to FieldManager.UpdateChildren(this, transaction). This call eventually results in the Child_Insert(Customer parentObject, DbTransaction transaction) method being invoked.
#region Data Access - Insert
/// <summary>
/// Save the current instance
/// </summary>
protected override void DataPortal_Insert()
{
//Create the db connection
Database db = new OracleDatabase(ManagedConnectionString.Instance.ConnectionString);
CommandCriteria criteria = new InsertCommandCriteria(this);
using (DbConnection connection = db.CreateConnection())
{
connection.Open();
using (DbTransaction transaction = connection.BeginTransaction())
using (DbCommand command = criteria.GetCommand(db, this, ConcurrencyCommandType.Insert))
{
try
{
//Insert Self
db.ExecuteNonQuery(command, transaction);
//Update Children
FieldManager.UpdateChildren(this, transaction);
//Commit Transaction
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
Log.FatalFormat("Customer:DataPortalInsert Failure.", ex.Message);
throw;
}
}
}
}
#endregion
And of course the ChildDataPortal Insert method.
#region Child Data Access - Insert
/// <summary>
/// Save the current instance
/// </summary>
/// <param name="parentObject">The parent object.</param>
/// <param name="transaction">The transaction.</param>
private void Child_Insert(Customer parentObject, DbTransaction transaction)
{
try
{
//Save Address Child
FieldManager.UpdateChildren(this, transaction);
Database db = new OracleDatabase(ManagedConnectionString.Instance.ConnectionString);
CommandCriteria criteria = new InsertCommandCriteria(parentObject.Id, this);
using (DbCommand command = criteria.GetCommand(db, this, ConcurrencyCommandType.Insert))
{
db.ExecuteNonQuery(command, transaction);
LoadProperty<int>(IdProperty, (int)db.GetParameterValue(command, "DB_KEY_out"));
LoadProperty<ConcurrencyControlItem>(ConcurrencyControlItemProperty, db.GetConcurrencyControlItemParameterValue(command));
}
}
catch (Exception ex)
{
Log.FatalFormat("Child_Insert Failure.", ex.Message);
throw;
}
}
So how does CSLA determine what method to call?
1. The FiledManager loops through all of its registered objects looking for child objects that implement IEditableBusinessObject or IEditableCollection.
2. Eventually a call to the GetMethod(Type objectType, string method, params object[] parameters) on the MethodCaller class is made for each child object.
Step two is where the important stuff is. How does Rocky determine what overload of Child_Insert to call? After all there is nothing stopping you from having 51 different Child_Insert methods 1 for each of your daddies! For instance a Address child object may be a child of several Root objects in your domain. Outlined below are the steps Rocky goes through when deciding what overload to call.
Lets try Strongly Typed?
Rocky first attempts to find a method with the same name and same number and types of parameters. Easy enough!
Well how about a little less Strongly Typed
If the first attempt fails to find a method CSLA will look for a method with the same name and the same number of parameters. Hummmm?! This can cause problems. We very well could have 2 methods with the same name and the number of arguments. If this happens CSLA throws and a AmbiguousMatchException.
Fuzzy Time (Not sure why he calls the method ‘FindMethodUsingFuzzyMatching’)
If CSLA throws a AmbiguousMatchException Rocky catches it and attempts a fuzzy match. That is the framework inspects both number of parameters as well as their type.
Can’t Find Jack!
If none of the above result in a match. CSLA says fine! Look for a method with the specified name only.
Now you know the rest of the story.

Imagine you have a user story the requires you to edit a customers invoices through the customer object. A perfectly valid scenario by the way. What you would probably do is create a view that loads a customer by its Id along with the its collection of invoices. Now if you were to say, change some data in a specific Invoice that resulted in a business rule breakage, both the Customer, InvoiceCollection, and the actual Invoice who’s rule your broke would be marked invalid. Because the object graph is now invalid saving the customer object is not possible and rightly so! However the problem arises when you attempt to tell the user what went wrong. The UI of course has access to the BrokenRulesCollection. See below.