Object design

Object design

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


sunny posted on Tuesday, July 28, 2009

I am having a hard time deciding between info object and editable object below is my scenario.

 

Root object (Matter)

Matter Id

Matter reported date

.

.

Contacts (of Mattercontacts)

 

Childlist object (MatterContacts)

 

   Child object (Mattercontact) 

      Suffix

      Role

      Contact id (SSN or FID)

            .

ObjectList  MasterContacts

 

   Object   MasterContact

      Contact id (SSN or FID)

      First Name

      Last Name

      Company Name

      DOB

      Address 1

      City  

      State

      ZIP

 

 

One off the properties of the child object mattercontact is the SSN or FID. When a user in the UI adds a contact (associates a contact) to the matter they have the option of choosing from existing list of mastercontacts in the system or adding a new one to the master contacts list and associating that contact with the matter in one step.

 

Please advice.

RockfordLhotka replied on Tuesday, July 28, 2009

You have two overlapping usage scenarios here.

One is that the user can associate a contact with a matter. So you'll probably have MatterEdit with a list of ContactAssociation objects - all editable. And you'll have a read-only list of ContactInfo objects they can select from.

Another usage scenario is adding a contact, which is really a separate scenario that the user can perform - basically temporarily interrupting the original scenario. To do this, you'll probably have a ContactEdit object. When it saves, the read-only list of ContactInfo will refresh so the new contact is in the list (there are a few ways to do that).

Your controller/UI code/whatever is using the objects can also detect the save completion and can add the association.

 

sunny replied on Wednesday, July 29, 2009

Thank you, I shall do that.

Just one more thing, can an editable root object have both readonlychildlist and editablechild objects. I was not sure how it would work. I was not being able to find any examples of it.

Really appreciate your quick response and help.

Sunny

RockfordLhotka replied on Wednesday, July 29, 2009

Technically yes, but generally it isn't the best idea.

Remember that, in a 3-tier deployment, the object graph moves from server to client on a fetch, and from client-to-server-and-back on a save. The "object graph" includes the root object, and any objects it references.

That would mean your read-only list would round-trip too, and probably for no reason.

So it is better to model this as a using relationship rather than a containment relationship.

Containment is where one object contains another - a parent-child relationship. The root object contains its child objects, and they travel together.

Using is where one object references another, but there is no parent-child relationship. The objects travel separately, and just interact as needed.

RedShiftZ replied on Wednesday, July 29, 2009

RockfordLhotka:

Using is where one object references another, but there is no parent-child relationship. The objects travel separately, and just interact as needed.



Rocky,
  Is there an example of this somewhere? If it's in the ProjectTracker, could you point out where?

Thanks,

Jeff Young

RockfordLhotka replied on Wednesday, July 29, 2009

You can look in ProjectTracker to see how a new resource is assigned to a project. The usage scenario centers around the Project object, but makes use of ResourceList.

 

Rocky

 

sunny replied on Wednesday, July 29, 2009

Hi,

Thanks, I took a look at projecttracker code; I am still not clear about the difference between containment and using. The below code from project.vb (EditableRootObject)

Private Shared ResourcesProperty As PropertyInfo(Of ProjectResources) = RegisterProperty(New PropertyInfo(Of ProjectResources)("Resources"))

Public ReadOnly Property Resources() As ProjectResources

Get

If Not FieldManager.FieldExists(ResourcesProperty) Then

LoadProperty(Of ProjectResources)(ResourcesProperty, ProjectResources.NewProjectResources())

End If

Return GetProperty(Of ProjectResources)(ResourcesProperty)

End Get

End Property

my understanding is that this is a reference to  (ProjectResources) EditableChildList

if this is an example of using then, if this were implemented as containment what would the code be like. I am sorry to keep bothering you as I am trying to figure the best approach to design my BO. I do not have a lot of experience in .NET and new to CSLA (just been reading your expert vb 2008 book).

My requirement is this

·        A user creates a matter

·        adds LOB specific Info to the matter (matter to LOBdata is one - to -one)

·        Associates existing contacts to matter and specifies the role they play (one - to many)

·        adds notes and attachments to matter ( one - to -many)

So this is what I came up with

Matter (editablerootobject)

   matterid

   matterdate

   LOBData as ECLOB (Editablechild object)

   Contacts as RLContacts (readonly collection)

   Notes as RLNotes (readonly collection)

The Matter fields and LineOfBusiness (LOBData) fields are all shown in the same tab. The Contacts and Notes are displayed on different tabs in the grids. When the user edits the matter fields he or she does not necessarily modify contacts or notes.

My reason for making the contacts and notes as ReadOnlyList objects was that they both have huge number of fields and rows (100s).  By making them ReadOnlyObjects I could design the object to have only the necessary fields required to display in the grid. If the user was going to edit / add or delete the contacts at that point I would create a new ERContact or get existing ERContact and allow adding /editing/deleting to it.

 Thanks in advance I really appreciate all your guidance and help.

 

RockfordLhotka replied on Wednesday, July 29, 2009

Project contains ProjectResources. ProjectResources is an editable child list that is owned/contained by Project.

 

ResourceList, on the other hand, is used as part of the assign a resource usage scenario when the user clicks on a button or link to assign a resource to the project. That’s all orchestrated by the UI code (code-behind, controller, or whatever model you are using – ProjectTracker uses code-behind).

 

So technically there’s not even a using relationship between Project and ResourceList, because the UI acts as an intermediary.

 

Rocky

 

JoeFallon1 replied on Wednesday, July 29, 2009

Yes.

I do that all the time.

In the Dataportal_Fetch you just load up the ROC using whatever key values are in the Root BO.

No need to "save" the ROC but it can be useful to loop over it to check other values that do need to be saved.

Joe

 

RockfordLhotka replied on Wednesday, July 29, 2009

The other thing you can do to retrieve several root objects at once is to use a ‘unit of work’ object. Basically a ReadOnlyBase or CommandBase subclass that brings back a group of objects as required for a usage scenario (typically to populate a UI form/page).

 

For example:

 

[Serializable]

public class CustomerDataRetriever : ReadOnlyBase<CustomerDataRetriever>

{

  public CustomerEdit Customer { get; private set; }

  public CategoryList Categories { get; private set; }

 

  public static CustomerDataRetriever GetData(int custId)

  {

    return DataPortal.Fetch<CustomerDataRetriever>(

      new SingleCriteria<CustomerDataRetriever, int>(custId));

  }

 

  private void DataPortal_Fetch(

    SingleCriteria<CustomerDataRetriever, int> criteria)

  {

    this.Customer = DataPortal.Fetch<CustomerEdit>(

      new SingleCriteria<CustomerDataRetriever, int>(criteria.Value));

    this.Categories = DataPortal.Fetch<CategoryList>();

  }

}

 

This UOW object goes through the data portal and loads a CustomerEdit and CategoryList object while on the server, and returns both objects to the caller. The caller (probably the UI) can now use both objects to bind to the UI and let the user do what’s needed.

 

I usually use ROB subclasses like this to retrieve data, because they are simple and fast.

 

For a save operation you need to use a CommandBase subclass, because your editable root objects need to round-trip – go to the server, and come back.

 

Rocky

 

Copyright (c) Marimer LLC