Inheritance of Business Objects Seems to break down

Inheritance of Business Objects Seems to break down

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


jdelano posted on Wednesday, August 09, 2006

I have two classes called Relationship and Employment and they are declared as follows:

Public Class Relationship
   Inherits BusinessBase(Of Relationship)
   ...
End Class

Public Class Employment
   Inherits Relationship
   ...
End Class

I then want to create a collection class called Employments, which I declared as follows:

Public Class Employments
   Inherits BusinessListBase(Of Employments, Employment)
   ...
End Class

The problem is that I get the following error: "Type argument 'Employment' does not inherit from or implement the constraint type 'BusinessBase(Of Employment)'"

I'm kinda new to Generics, and that's what I'm suspecting is causing this issue. Any ideas on how to solve it? I know I could probably use composition instead of inheritance, but in this particular case (using the "behaves-as" or "is-a" test), inheritance makes the most sense. Any ideas?

Thanks,

John Delano

RockfordLhotka replied on Wednesday, August 09, 2006

Hmm, I just tried the following (in 2.0.3) and it compiles:

Public Class R
  Inherits BusinessBase(Of R)

  Protected Overrides Function GetIdValue() As Object
    Return 0
  End Function

End Class

Public Class E
  Inherits R

End Class

Public Class LR
  Inherits BusinessListBase(Of LR, E)

End Class


I think you may find the solution is to upgrade to 2.0.3. The type constraint for C on BusinessListBase is now Csla.Core.IEditableBusinessObject, rather than on Csla.Core.BusinessBase, and perhaps that resolves the issue (though I really don't see why it would).

jdelano replied on Thursday, August 10, 2006

Okay, I'm sorry... I left out a critical piece of information...

I'm trying to create my own "BusinessBase-like" generic class. All of my business objects have the same exact type of ID (Integer) and they all have a Description, so I thought I'd encapsulate that in a "MyProjectBase" class (which inherits from BusinessBase). I also wanted to create my own generic "MyProjectListBase" class (which inherits from BusinessListBase) to handle the Assign, GetItem, Remove, Contains, etc. in one place (do I even need to implement these, by the way?), so here's what I did...

Public MustInherit Class MyProjectBase(Of T as MyProjectBase(Of T))
   Inherits BusinessBase(Of T)
   ...
End Class

Public MustInherit Class MyProjectListBase(Of T as MyProjectListBase(Of T, C), C As MyProjectBase(Of C))
   Inherits BusinessListBase(Of T, C)
   ...
End Class

Then, I declared the classes from my first post as follows:

Public Class Relationship
   Inherits MyProjectBase(Of Relationship)
   ...
End Class

Public Class Employment
   Inherits Relationship
   ...
End Class

Public Class Employments
   Inherits MyProjectListBase(Of Employments, Employment)
   ...
End Class

Then I get the error I mentioned in my first post. So, I did some thinking after your comment that BusinessListBase's type constraint is IEditableBusinessObject, and I did the same thing in the MyProjectListBase class, and then it worked. The only problem is that now MyProjectListBase doesn't know about any of the fields/properties I've declared in MyProjectBase. In order to implement that functionality, do I need to create another layer of inheritance that isn't generic and stick it in the middle somehow? If so, do you have any ideas on how (i.e. syntax) I would need to accomplish that?

I guess the worst case scenario is that I'll have to implement common collection methods in all my collection classes... not the end of the world, I guess.

Thanks for any help,

John Delano

RockfordLhotka replied on Thursday, August 10, 2006

It is best to use inheritance to abstract _behavior_, not _data_. So using inheritance to provide common properties is an iffy thing to do (not impossible, but somewhat problematic). On the other hand, if those properties have extensive behavior associated with them, then that's another matter.
 
If all you want is a consistent interface for polymorphism, then an interface (often inheriting from IEditableBusinessObject) is the right answer.
 
So what you are doing for the businessbase subclass is fine. But you MUST use a derivative of IEditableBusinessObject to get polymorphic behaviors within a collection.
 
http://www.lhotka.net/Article.aspx?area=4&id=b8515cd9-7f8e-43df-9efd-cd958dfdc21a
 
This is because generics aren't polymorphic and so you need some non-generic type that all your objects have in common.
 
Rocky

I'm trying to create my own "BusinessBase-like" generic class. All of my business objects have the same exact type of ID (Integer) and they all have a Description, so I thought I'd encapsulate that in a "MyProjectBase" class (which inherits from BusinessBase). I also wanted to create my own generic "MyProjectListBase" class (which inherits from BusinessListBase) to handle the Assign, GetItem, Remove, Contains, etc. in one place (do I even need to implement these, by the way?), so here's what I did...

jdelano replied on Thursday, August 10, 2006

Thanks, Rocky! That's perfect! I don't know why I didn't think of using an interface before, but that's essentially all I need.  Thanks!

John

Copyright (c) Marimer LLC