Refactoring with CSLA

Refactoring with CSLA

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


OscarLauroba posted on Monday, April 27, 2009

Here it's another one taking my first steps in CSLA world.
The properties of businesses class are not only strings, integers or booleans and I want to do a little practice to learn how to abstract common code.
I would like to consider some refactoring in the projectTracker, following the wise advices of Martin Fawler's book "Refactoring: Improving the Desing of Existing Code".
Let's assume we want to extract the two Started and Ended properties of the Project class into a new one Period class.
And also we want to extract the validation code of these two dates properties. If Ended has a value, this has to be later than Started. And Started is requiered.
This would allow me to reuse the Period class in any other object.
For example, Resource class could have a ContractPeriod property of Period Type.

How can I do this?
 
What I'm pretending is something like this:

Class Period

 Private Shared StartedProperty As PropertyInfo(Of SmartDate) = RegisterProperty(New PropertyInfo(Of SmartDate)("Started"))
  Public Property Started() As String
    Get
      Return GetProperty(Of SmartDate, String)(StartedProperty)
    End Get
    Set(ByVal value As String)
      SetProperty(Of SmartDate, String)(StartedProperty, value)
    End Set
  End Property

  Private Shared EndedProperty As PropertyInfo(Of SmartDate) = RegisterProperty(New PropertyInfo(Of SmartDate)("Ended", New SmartDate(SmartDate.EmptyValue.MaxDate)))
  Public Property Ended() As String
    Get
      Return GetProperty(Of SmartDate, String)(EndedProperty)
    End Get
    Set(ByVal value As String)
      SetProperty(Of SmartDate, String)(EndedProperty, value)
    End Set
  End Property

' ... Validation Code

End Class

And then, to replace the two properties in the Project Class by a reference to this new class:

Private Shared ProjectPeriodProperty As PropertyInfo(Of Period) = RegisterProperty(New PropertyInfo(Of Period)("ProjectPeriod"))

Public Readonly Property ProjectPeriod() As Period

Get

Return GetProperty(Of Period)(ProjectPeriodProperty)

End Get

End Property

Now, if the UI developer wanted to access the project's dates would be able to write :

Dim _project as Project.GetProject(idProject)
Dim _startedDate as string = myProject.Period.Started
Dim _endedDate as string = myProject.Period.Ended

instead of

Dim _startedDate as string = myProject.Started
Dim _endedDate as string = myProject.Ended

I have the same question about objects that have a key of several fields.
If Resource object requiered compound keys (i.e. CompanyId and ResourceId )fields, Would it be unadvisable to extract the properties in a new Key Class and reuse it for the Criteria class?
Fields in the criteria class are sometimes already defined in the business class.

   _resource.Key.CompanyId=dataReader.GetString("CompanyId")
   _resource.Key.EmployeeId = dataReader.GetInteger("EmployeeId")

Can I DataBind a property that's not a build-in type, like would be Period Class?
Should these little components be child-objects? Validation for Started and Ended properties would have to be in the child-object?

Any sample that uses some property referring to another class will be welcome.
Could I reuse the same Period Class in a ResourceInfo class to show the contract dates of the Resource to the user or Should I write a ReadOnlyBase PeriodInfo?

Thank you very much for spending your time reading this.

Oscar.

PS: Excuse me for my poor English.

RockfordLhotka replied on Monday, April 27, 2009

OscarLauroba:

Let's assume we want to extract the two Started and Ended properties of the Project class into a new one Period class.

The OO design philosophy supported by CSLA .NET is that objects are defined by behavior (reponsibility), not data.

So the only reason you would do what you are describing is that your use case had some business requirement that defined a responsibility this Period class would fulfil. In other words, the job of the Period class must be substantially different from the job of the Project class or this doesn't make sense to start with.

Beyond that, you have to consider that you are living in the .NET world, so you probably want your objects to be available for data binding. Otherwise you'll have to invent your own UI data binding infrastructure like people do on other platforms. That would be unpleasant!

Not all data binding technologies support dot notation - which means that you really want to keep your object properties flat if you want to work with all UI types.

OscarLauroba replied on Wednesday, April 29, 2009

Thank you, Rocky, for your quick reply.

Well, it seems that I'm not the only one worried about how to nesting editable child objects. I've been searching this forum and could find several subjects such as Nested B.O., Nested Properties, etc. (Sometimes it's hard to match what you're looking for.)

I have a property that is an editable child object (not an editable child list). This child object has two properties and its validation rules (data and behaviour Smile [:)]). All seems working fine but the errorProvider of the winform. It doesn't show the error message if the validation of the child properties object fails.

Rocky, Have you written any article talking about this? Do you think it's worth the effort? Is this a problem caused by not keeping my object properties flat?

Thanks once more.

Oscar.

 

RockfordLhotka replied on Wednesday, April 29, 2009

The problem is that I don’t know of a good solution, so I’m not sure what an article would say :)

 

In WPF/SL the issue is a little easier to deal with, because you can control the binding at a more granular level. But in Windows Forms it is really quite hard, because the binding is at the parent object level, and they really don’t seem to support the concept of binding to a child that isn’t in a collection.

 

Rocky

 

Copyright (c) Marimer LLC