Editable collection with properties

Editable collection with properties

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


sash_kr posted on Sunday, March 16, 2014

Rockford Lhotka says:

"Collections do not support direct declaration of properties, so you can’t implement properties in this class. If properties are required in addition to the list of child objects, you should create an editable parent object that contains the collection, along with those other properties and their rules."

 

So, I decided to check this out.

I've declared simply property in my inherited BusinessBindingListBase. Somethink like this:

property long DocId { get; set; }

 

I can do "Fetch" and "Update". And it works. My custom property always persist.

But I'm working with 2-tier mode.

 

Maybe it will not work in 3-tier? What reasons could stop me from using custom properties in BusinessBindingListBase?

ajj3085 replied on Sunday, March 16, 2014

The issue is that the MS databinding technologies won't look for properties on collections and you won't be able to use them.

Also Csla doesn't support this (which beyond the databinding reasons, collection classes should just be collections to keep with SRP) so if you do go to 3 tier mode your property will lose its value.

sash_kr replied on Monday, March 17, 2014

"The issue is that the MS databinding technologies won't look for properties on collections and you won't be able to use them."

I don't need databinding technology for that property. So this is not my case.

 

"so if you do go to 3 tier mode your property will lose its value."

Are you sure or you think it that will loose it's value? BusinessBindingListBase supports IClonable interface. ObjectCloner class clones my  BusinessBindingListBase with all custom properties. So I think it should  works correctly in 3 tier mode.

So, 100% it will not work?

swegele replied on Monday, March 17, 2014

I am like you...I don't want databinding.  I am just tracking some information for internal and temporary purposes...no IsDirty or anything like that.  Not even a property...just a variable!

Just a simple value to pass along with my BusinessListBase.

IT WORKS and in 3 tier mode.  The value gets serialized just fine. 

***The only time I saw any issues was when a parent business object creates the child list through the ChildDataPortal.  The value was lost (nothing) in that case when the parent was serialized across the portal in 3 tier mode.  But in that case I realized I could just do what I needed before coming back from the portal.

But on all my lazy loaded BusinessListBase objects, when they came back from the full DataPortal_Fetch the value was there.

I do not use the PropertyInfo objects...just a private backing field like "Private mSomething as String"

Hope this helps.

JonnyBee replied on Monday, March 17, 2014

Hi.

CSLA .NET may be configured to use other serializers than the builtin .NET binary serializers (BinaryFormatter/NetDataContractSerializer) and then you must add extra code in your list to make sure these values is passed on to the client. This is necessary for f.ex WindowsMobile, WindowsStore and Silverlight applications. You may now also use these serializers in .NET clients.

So to make sure that a member variable is always transfered between tiers you shoul override and add code to OnGetState/OnSetState in the list class:

This is tha actual code in BusinessListBase.cs:

/// <summary>
/// Method called by MobileFormatter when an object
/// should serialize its data. The data should be
/// serialized into the SerializationInfo parameter.
/// </summary>
/// <param name="info">
/// Object to contain the serialized data.
/// </param>
protected override void OnGetState(SerializationInfo info)
{
  info.AddValue("Csla.BusinessListBase._isChild", _isChild);
  info.AddValue("Csla.BusinessListBase._editLevel", _editLevel);
  base.OnGetState(info);
}
 
/// <summary>
/// Method called by MobileFormatter when an object
/// should be deserialized. The data should be
/// deserialized from the SerializationInfo parameter.
/// </summary>
/// <param name="info">
/// Object containing the serialized data.
/// </param>
protected override void OnSetState(SerializationInfo info)
{
  _isChild = info.GetValue<bool>("Csla.BusinessListBase._isChild");
  _editLevel = info.GetValue<int>("Csla.BusinessListBase._editLevel");
  base.OnSetState(info);
}

sash_kr replied on Monday, March 17, 2014

So, if my library will be executed f.ex. in WinForms only - everything will work great. But when it should be used not only in WinForms but in WindowsMobile, WindowsStore or Silverlight I should manually add code to OnGetState/OnSetState? Am i correct?

swegele replied on Monday, March 17, 2014

That's correct...I just tested it last night.  And like you I am NOT targeting Silverlight, WP, or WinRT etc. so I did not do the OnGet and OnSet.

JonnyBee replied on Monday, March 17, 2014

Hi,

Assuming that you will be using the default BinaryFormatter and WindowsForms then yes- everyting will work. 

You may opt to use the other serializer (f.ex. to incorporate compression) and then you ned the OnGetState/OnSetState overrides. 
It doesen't add that much code and will make it easier to experiment with or move to the MobileFormatter based serialization at a later stage.  

Copyright (c) Marimer LLC