OnDeserialized is missing

OnDeserialized is missing

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


tiago posted on Thursday, November 05, 2009

Hi Rocky.

As you might know (well... maybe you don't) CslaGen relies on events to extend the base functionality of the generated code. Those events are setup on an overriden Initialize() method. There is no problem if CslaAutoCloneOnUpdate is false.

In future releases of Csla, the standard will be CslaAutoCloneOnUpdate is true. This means that the event handlers we setup in the Initialize() method will be gone when we update/save/clone the object - the object is cloned but the non-serializable part will be lost.

The solution is to override OnDeserialized (System.Runtime.Serialization.StreamingContext context).

The problem is some object stereotypes don't support OnDeserialized so there is nothing to override. How can we be sure to re-setup the event handlers on update/clone?

On Csla 3.0.5 the problems affects ReadOnlyList and NameValueList.
On Csla 3.7.1 besides the above lists, it also affects BusinessListBase!

Any directions?

RockfordLhotka replied on Thursday, November 05, 2009

I just looked at the BLB code, and OnDeserialized() is a protected virtual method. It only shows up in Intellisense if you have show advanced members turned in on Visual Studio, but it is there.

For the other two types you can do the following:

[System.Runtime.Serialization.OnDeserialized]
private void OnDeserializedHandler(System.Runtime.Serialization.StreamingContext context)
{
  OnDeserialized(context);
}

protected virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
{
  // put your code here
}

Since you are doing code-gen, you can just gen this entire block of code - putting your event handling stuff in the "your code here" location.

I'll add this to the wish list for a future fix - but I'm now working on version 4.0, so that's where the fix will come in.

tiago replied on Friday, November 06, 2009

Thanks.

If you don't mind, I'll quote you on CslaGen group.

Patrick.Roeper replied on Friday, January 15, 2010

Just to follow up on this...

CommandBase is one of these stereotypes that doesn't have an extension point for handling OnDeserialized correct?

Since I have my own set of base classes, I will need to use the _forceInit trick (pg 249-250 C# 2008), which means I need to include...

[System.Runtime.Serialization.OnDeserialized]
private void OnDeserializedHandler(System.Runtime.Serialization.StreamingContext context)
{
  OnDeserialized(context);
}

protected virtual void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
{
  // put your code here
}


... in my base class. Did I miss anything?

Edit:

Just to add a little bit of context to this, I am using v3.8 for silverlight, and my property declarations use the syntax:

public virtual string Username
{
  get { return ReadProperty(UsernameProperty); }
  private set { LoadProperty(UsernameProperty, value); }
}
private static readonly PropertyInfo<string> UsernameProperty = RegisterProperty<string>(x => x.Username);


Maybe this hack isn't needed anymore?

RockfordLhotka replied on Friday, January 15, 2010

Current versions of CSLA .NET include a "force init" routine that normally solves the static field init problem.

On Silverlight however, this routine is only reliable if you declare your PropertyInfo<T> fields as public.

The reason is that the routine uses reflection to "touch" a static member on each class in the inheritance hierarchy, thus forcing static initialization of all fields in that class. In Silverlight however, reflection only works against public members, so any class having zero public static fields won't be automatically initialized.

Copyright (c) Marimer LLC