Inheriting from a business object

Inheriting from a business object

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


PaulD posted on Thursday, June 01, 2006

OK, so I have a base class called ThirdParty, and have 2 derived classes from that; Person and Company.

Most of the information I need is stored up in ThirdParty, and the additional not so common bits in Person and Company.  The ThirdParty is responsible for saving its data and the dervived objects is responsible for saving its data.  So far so good?  Right?

Except one small little snag.  It doesn't work! (heh)

ThirdParty can't exist on its own, so I've made it abstract:

Public MustInherit Class ThirdParty

Inherits BusinessBase(Of ThirdParty)

The base object simply inherit from this:

Public Class Person

Inherits ThirdParty

Now, the problem is the fact ThirdParty is abstract so CSLA can't create an instance of it.  So I get this error.

ThirdPartyTestFixture.ThirdPartyPerson_CreateAndReadBack : Csla.DataPortalException : DataPortal.Fetch failed
  ----> System.MissingMethodException : Cannot create an abstract class.

I appreciate the error, obviously it can't create an abstract class.  *but* has anyone successfully acheived this in another way?  All help greatly appreciated :)

Paul

PaulD replied on Thursday, June 01, 2006

I saw Rockys previous post on this subject, where you pass the type into the base class.  However, having done that, I now get:

ThirdPartyTestFixture.ThirdPartyPerson_CreateAndReadBack : Csla.DataPortalException : DataPortal.Fetch failed
  ----> System.ArgumentException : Cannot create an instance of XXXX.ThirdParties.ThirdParty`1[T] because Type.ContainsGenericParameters is true.

I'm using CSLA 2.0.1 as suggested.

My abstract class now looks like:

Public MustInherit Class ThirdParty(Of T As ThirdParty(Of T))

Inherits BusinessBase(Of ThirdParty(Of T))

 

stefan replied on Thursday, June 01, 2006

Hi Paul,

PaulD:

My abstract class now looks like:

Public MustInherit Class ThirdParty(Of T As ThirdParty(Of T))

Inherits BusinessBase(Of ThirdParty(Of T))


Public MustInherit Class ThirdParty(Of T As ThirdParty(Of T))

Inherits BusinessBase(Of T)

should work

Stefan


RockfordLhotka replied on Thursday, June 01, 2006

It sounds like your Criteria class is in the base class, so the data portal is trying to create an instance of the base class - which it can't, because that class is generic (and of course abstract, but it doesn't even get that far).

You need to either move your criteria class to the non-generic subclass that is your actual business object, or you need to have it inherit from CriteriaBase so you can specify the non-generic subclass type in the criteria object's constructor.

Somehow you need to tell the data portal what non-generic type it is supposed to create.

PaulD replied on Thursday, June 01, 2006

Hi Rocky,

Yeh you hit the nail on the head with that one.  I changed my Criteria to be:

#Region " Criteria class"

<Serializable()> _
Public Class ThirdPartyCriteria(Of T As BusinessBase)
Inherits CriteriaBase

#Region " Private declarations"
   
Private _thirdPartyId As Guid
#
End Region

#Region " Constructors"
   
Public Sub New(ByVal thirdPartyId As Guid)
   
MyBase.New(GetType(T))
   _thirdPartyId = thirdPartyId
End Sub
#End Region

...

And it works perfectly.

Thanks :)

mr_lasseter replied on Saturday, June 24, 2006

I am having the same problem.  After reading the posts I changed my Base Object to the what is below.  Everything now complies, but the DataPortal_Fetch Cannot find the correct method since it is looking for DataPortal_Fetch (object).  What am I doing wrong? 

My goal for doing this is to allow all my data access to take place in the in Base Class (using Code Gen) and have all the business logic included in the Project Class.  I have thought about using partial classes to accomplish this, but I would like to have the ability to override the base class functionality if necessary.  Any thoughts and help would be greatly appreciated. 

Public MustInherit Class ProjectBase(Of T As ProjectBase(Of T))

Inherits BusinessBase(Of T)

...

Protected Class Criteria(Of ProjectBase)

Inherits CriteriaBase

...

Private Overloads Sub DataPortal_Fetch(ByVal criteria As Criteria(Of ProjectBase(Of T)))

kdlc replied on Saturday, June 24, 2006

Check This Post: http://forums.lhotka.net/forums/thread/1052.aspx

mr_lasseter replied on Monday, June 26, 2006

The link you provided does not help as the criteria object was created in the sub classes not the base class.  My problem is if I create the Criteria Class and Data Portal methods in the Base Class then the call DataPortal.Fetch(Of Project)(New Criteria(Of Project)(Id)) from the sub class, the code never actually calls the DataPortal_Fetch in the Base Class since the signature of the function is not

DataPortal_Fetch(ByVal criteria As Criteria)

But is

DataPortal_Fetch(ByVal criteria As Criteria(Of ProjectBase(Of T))

Am I making any sense?

RockfordLhotka replied on Monday, June 26, 2006

I am at a client site until June 29, with limited email until then.

Thank you for your understanding,

Rocky

mr_lasseter replied on Thursday, July 06, 2006

Any ideas on what I can do?

 

Thanks.

RockfordLhotka replied on Thursday, July 06, 2006

I never intended for criteria classes to be generic. My guess is that the data portal code that invokes the DataPortal_XYZ methods would need extra code to deal with generic parameters.

Criteria classes are supposed to be simple DTO (data transfer object) style objects that just ferry your criteria data from the client to the server. I haven't had time to read this thread and understand why you'd be making the criteria class generic?

mr_lasseter replied on Thursday, July 06, 2006

Rocky,

Thanks for taking time to answer the post.  What I am trying to do is use code generation to handle all the database access for my business objects.  I thought I would create a base class for each business object that would contain all database access code as well as private variables and public members.  My actual business objects would inherit from these base classes and implement all the business rules. This way if something changed in the database, I could regenerate the database access code without losing all the business rules.  I hope I am making sense.

Do you have any advice on how to go about accomplishing this?  Would you use partial classes or not do this at all? 

Thanks.  Mike

RockfordLhotka replied on Thursday, July 06, 2006

This is quite common, and is the basis for the CodeSmith templates, CSLAgen and various other tools and templates out there.
 
I'm not sure partial classes are the right approach, but a couple people have been working hard at trying to make them work - and I've slightly altered the framework to help (the Initialize() method in 2.0.1 is for partial class support).
 
I think the more traditional base-class-sub-class approach is cleaner overall. The CriteriaBase class is designed to enable this scenario, allowing you to generate your factory methods and criteria class in your generated base class.
 
You should check out http://forums.lhotka.net for various discussions on code-gen - see what others are doing and how they are approaching the problems.
 
Rocky
 
Rockford Lhotka  (rocky@lhotka.net)
Magenic Technologies Principal Technology Evangelist
Microsoft Regional Director and MVP


From: mr_lasseter [mailto:cslanet@lhotka.net]
Sent: Thursday, July 06, 2006 9:50 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Inheriting from a business object

Rocky,

Thanks for taking time to answer the post.  What I am trying to do is use code generation to handle all the database access for my business objects.  I thought I would create a base class for each business object that would contain all database access code as well as private variables and public members.  My actual business objects would inherit from these base classes and implement all the business rules. This way if something changed in the database, I could regenerate the database access code without losing all the business rules.  I hope I am making sense.

Do you have any advice on how to go about accomplishing this?  Would you use partial classes or not do this at all? 

Thanks.  Mike




RockfordLhotka replied on Thursday, July 06, 2006

Oops - didn't notice that this email WAS from the forum Surprise [:O]

Well then, I suggest that you check out some of the other threads on code-gen in the forum you are already reading Wink [;)]

Nothing you are trying to do is new or unique, and there are examples available (specifically the CodeSmith templates and Kathleen Dollard's code-gen book) that illustrate how to do what you want.

Copyright (c) Marimer LLC