How to implement Base class & Sub Classes ...

How to implement Base class & Sub Classes ...

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


kdlc posted on Tuesday, May 30, 2006

how can i implement this design using CSLA .NET?

Base Class      Sub Classes

Person   -->    Customer
            -->    Employee

Thanks in Advance!

 

 

DavidDilworth replied on Thursday, June 01, 2006

Option 1
Create abstract base class Person, inherit from BusinessBase.
Create concrete class Customer, inherit from Person.
Create concrete class Employee, inherit from Person.

Option 2
Create Interface IPerson.
Create concrete class Customer, inherit from BusinessBase, implement IPerson.
Create concrete class Employee, inherit from BusinessBase, implement IPerson.

I'd say that the choice depends on what you are trying to model in your concept of a Person.

What is it that the Person object represents?  Does it need behaviour?  What can you do with a Person?  Do you want to get collections of Person for common processing?

HTH

LayeredDev replied on Thursday, June 01, 2006

Or

Option 3
Create concrete class Person.
Create concrete class Customer, containing an object of class Person.
Create concrete class Employee, containing an object of class Person.

If you want a Person to be used without referring to the Person as a Customer or an Employee, the above option may suit you. As David says, it all depends on what you are trying to model in your concept of a Person.

Cosmic Ovungal

ajj3085 replied on Thursday, June 01, 2006

Don't forget option 3:

IPerson interface
Person abstract class (holds common behaviors, Inherits BusinessBase, implements IPerson, or pieces of it)
Customer (inherts Person; overrides functionality, implements abstract functionality not implemented)
Employee( inherits Person, etc etc.)

Of course this assumes there are common behaviors for Customer and Employee which likely won't change.

Which option you pick will of course depend on your use cases.

HTH
Andy

RanceDowner1234 replied on Wednesday, June 07, 2006

kdlc.  Try the following...

Imports Csla
Imports Csla.Data
Imports Csla.Validation

Imports System.Data.SqlClient '[or whatever database library]

<System.Serializable()> _
Public MustInherit Class Person(Of T As Person(Of T))
    Inherits BusinessBase(Of T)

    'No Factory Methods

    Protected Overridable Sub Fetch(ByVal dr As SafeDataReader)

        With dr
            'Fill private Variables
            'e.g. ... _LastName = .GetString("LastName")
        End With

    End Sub

    Protected Overridable Sub Update(ByVal cm As SqlCommand)

        With cm
            'fill command parameters with values from private variables
            'e.g ... .Parameters.AddWithValue("@LastName", _LastName)
        End With
    End Sub

End Class

<System.Serializable()> _
Public Class Customer
    Inherits Person(Of Customer)

    Protected Overrides Function GetIdValue() As Object
        'Return Something
        'e.g. .... Return _CustomerID
    End Function

    '
    'Factory Methods
    '
    Public Shared Function GetInstance(ByVal id As Integer) As Customer
        Return DataPortal.Fetch(Of Customer)(New Criteria(id))
    End Function

    '
    'Data Methods
    '
    <Serializable()> _
    Private Class Criteria

        Private mId As Integer
        Public ReadOnly Property Id() As Integer
            Get
                Return mId
            End Get
        End Property

        Public Sub New(ByVal id As Integer)
            mId = id
        End Sub
    End Class

    Protected Overrides Sub Fetch(ByVal dr As SafeDataReader)

        Call MyBase.Fetch(dr) 'Call Base Class Fetch
        With dr
            'fill customer variables
            'e.g. _Customer AddressLine1 = .GetString("AddressLine1")
        End With

    End Sub

    Private Overloads Sub DataPortal_Fetch(ByVal criteria As Criteria)

        Using cn As SqlConnection = New SqlConnection("<insert connection string>")
            cn.Open()
            Using cm As SqlCommand = cn.CreateCommand
                cm.CommandType = CommandType.StoredProcedure
                cm.CommandText = "[Call a stored Proc]"

                Using dr As New Data.SafeDataReader(cm.ExecuteReader)
                    dr.Read()
                    With dr
                        Call Me.Fetch(dr)
                        MarkOld()
                    End With
                End Using
            End Using
        End Using

    End Sub

    Protected Overrides Sub Update(ByVal cm As SqlCommand)
        MyBase.Update(cm) 'Call Base Class to update it's parameters
        With cm
            'Update customer parameters
            'e.g. ... .Parameters.AddWithValue("AddressLine1", _AddressLine1)
        End With
    End Sub

    <Transactional(Csla.TransactionalTypes.Manual)> _
    Protected Overrides Sub DataPortal_Update()

       Dim cn As SqlConnection 
      'Instantiate cn ... e.g. ... cn = New SqlConnection("<insert connection string>")

      Dim trans As SqlTransaction 
      trans = cn.BeginTransaction( )

        If Me.IsDirty Then
            Using cm As SqlCommand = cn.CreateCommand
                cm.CommandText = "[Call _Update Stored Proc]"
                cm.Transaction = trans
                cm.CommandType = CommandType.StoredProcedure
                Try
                    Update(cm)

                    cm.ExecuteNonQuery()

                    trans.Commit()

                Catch ex As Exception
                    trans.Rollback()
                    Throw ex
                End Try
            End Using
        End If
    End Sub

End Class

AndrewCr replied on Friday, August 04, 2006

  (Sorry to add on to a slightly older thread, but my question is related...)

  First off, this bit of code was immensely helpful, thanks.  That said, I'm trying to create a collection (list) of base objects.  Since the base object is virtual (MustInherit) the objects in the collection will actually be instances of the child classes, but I want to be able to hold them all in the same collection.

  When I attempt to declare the list as (for example:

Public Class PersonList
   Inherits BusinessListBase(Of PersonList, Person)

  the compiler wants me to add a type argument to Person.  Of course, if I change it to:

Public Class PersonList
   Inherits BusinessListBase(Of PersonList, Person(Of Person))

  I'm back where I started, only one level deeper.  It will accept:

Public Class PersonList
   Inherits BusinessListBase(Of PersonList, Customer)

  but that defeats the point, since I want to be able to have other Person child objects in the list as well.  Perhaps I just don't understand generics well enough.

  Any help?

ajj3085 replied on Friday, August 04, 2006

I'd think you'd need a common interface and have the list accept anything which implements that interface... an IPerson.  Of course, your person abstract would implement this interface.  The catch is that you must have the IPerson interface implement IEditableBusinessObject, to make the C type parameter on BLB accept it.

So :

public interface IPerson : IEditableBusinessObject {
// Define your interface; just right click on your Person class and tell it to Extract
// interface..tweak to your liking.
}

public abstract Person : BusinessBase<Person>, IPerson {
// No changes should be needed here
}

Then your list:
public class PersonList : BusinessListBase< PersonList, IPerson> {
}

Sorry for the C#... but I'm don't work in Vb... but I hope it will be clear.

Let us know if that solves the problem for you.

Andy

AndrewCr replied on Friday, August 04, 2006

  Yes, I think this will work nicely.  Thanks very much.

Copyright (c) Marimer LLC