Inheritance Woes.

Inheritance Woes.

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


lwmorris posted on Monday, June 30, 2008

Has anyone experience problems when inheriting from another custom class? Specifically, I have two classes (Customer and Person) that work when each is directly inheriting from BusinessBase. However, if I change Customer to inherit from Person then I loose all the properties when the object is back on the server.

Any help would be appreciated!

 

[Serializable()]
public class Customer:Person
{

#region Factory Methods

public static Customer NewCustomer(){return DataPortal.Create<Customer>();}

private Customer() : base()

{ /* Require use of factory methods */ }

#endregion

protected override object GetIdValue(){return this.Id;}

private static PropertyInfo<Guid> IdProperty = RegisterProperty<Guid>(typeof(Customer), new PropertyInfo<Guid>("Id", "Id"));

public Guid Id
{
get{return GetProperty<Guid>(IdProperty);}
set{SetProperty<Guid>(IdProperty, value);}
}

#region Data Access

[RunLocal()]
protected override void DataPortal_Create(){}

protected override void DataPortal_Insert()
{
Customer c = this;
Guid id = this.Id;
}
#endregion
}

 

 

[Serializable()]
public abstract class Person:BusinessBase<Person>
{

private static PropertyInfo<string> NameProperty = RegisterProperty<string>(typeof(Person), new PropertyInfo<string>("Name", "Name"));

public string Name
{
get{return GetProperty<string>(NameProperty);}
set{SetProperty<string>(NameProperty, value);}
}
}

lwmorris replied on Monday, June 30, 2008

WOW! Found two solution.

1. Override OnDeserialized in my base class OR

2. Replace the ManagedProperties with local variables (on the base class only)

RockfordLhotka replied on Tuesday, July 01, 2008

Or

3. Implement a pattern to force the static fields of the base class to initialize. There are several techniques, I like this one the best (put this code in your base class):

private static int _dummy;

private BaseClassConstructor()
{
  _dummy = 0;
}

This ensures that the static fields of the base class (the RegisterProperty() calls) are executed before any properties are manipulated on the business object.

lwmorris replied on Wednesday, July 02, 2008

I tried the static dummy method and it didn't work. After my object is sent to the Webservice/WcfService, my properties all return an Invalid cast exception. Uncommenting the OnDeserialized fixes the problem.

Here's my updated base class:

[Serializable()]
public abstract class Person
:BusinessBase<Person>
{

#region Factory Methods
public static Person NewPerson()
{
return DataPortal.Create<Person>();
}

public static int _dummy;
protected Person(): base()
{
_dummy = 0;
}

//protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
//{
// base.OnDeserialized(context);
//}

#endregion

protected override object GetIdValue(){return this.Name;}

private static PropertyInfo<string> NameProperty = RegisterProperty<string>(typeof(Person), new PropertyInfo<string>("Name", "Name"));

public string Name{
get{return GetProperty<string>(NameProperty);}
set{SetProperty<string>(NameProperty, value);}
}

#region Data Access

protected override void DataPortal_Insert()
{
}
#endregion
}

RockfordLhotka replied on Wednesday, July 02, 2008

Oh yeah, I forgot about that part – you need to set _dummy in the OnDeserialized() override too.

 

Rocky

 

Annesh replied on Friday, August 22, 2008

Eish, after many hours - this solved all my problems. Thanks :-)

rsbaker0 replied on Friday, August 22, 2008

I didn't know this would work at all, since the Customer type isn't known to BusinessBase<T> and if you fetch using a Person.Criteria, you'll get a Person, not a Customer. (Of course, I suspose you could implement Customer.Criteria, etc.)

Is inheriting from BusinessBase<T> derived classes considered an OK/recommended practice?

ajj3085 replied on Friday, August 22, 2008

I think the workaround would be in any subclass of BusinessBase that is also subclassed.

Boris replied on Monday, October 06, 2008

>I think the workaround would be in any subclass of BusinessBase that is also subclassed.

Is that a guess?

I'm afraid, I'll have to put the fix pretty much in every class inheriting from MyBusinessBase (including MyBusinessBase) as long as they have some children (no backing fields)...or Not?

RockfordLhotka replied on Monday, October 06, 2008

That is not a guess. If you inherit from BusinessBase<T> more than 1 level (in other words, you have your own custom base class) then you MUST put the _forceInit code in every one of your classes.

 

Rocky

 

Boris replied on Monday, October 06, 2008

Yes...Many thanks for the quick reply!!

BusinessBase->MyBusinessBase->MyBoThatIsNotInheritedButHasChildren

For a second there I thought that one of last suggestions was:
putting the fix only in MyBusinessBase would be sufficient...
(Sorry if I misunderstood)

And, now if I understand correctly it needs to go to both:
MyBusinessBase & BOThatIsNotInheritedButHasChildren

 

Copyright (c) Marimer LLC