ListBase AddNewCore Override

ListBase AddNewCore Override

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


Wbmstrmjb posted on Wednesday, February 11, 2009

Does anyone see a problem with adding the following to the extended base class for editable lists?  I would think that all lists would want the same default functionality for AddNew.

 

protected override object AddNewCore()

{

decimal id = this.Count + 1;

id *= -1;

C obj = null;

Type cType = typeof(C);

string newMethod = "New" + cType.Name;

obj = (C)cType.InvokeMember(

newMethod,

BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static,

null,

null,

new object[] { id });

this.Add(obj);

return obj;

}

tetranz replied on Thursday, February 12, 2009

This might work but it seems overly complicated. I always create the id in the child's DataPortal_Create. The id sequence is kept in a static variable and decremented. You can use System.Threading.Interlocked.Decrement if it needs to be thread safe.

Using count seems like a potential problem because what happens if children are deleted?  You might have id -1, -2, -3, then delete -2 and add another. You'll then have -1, -3, -3.

I can see how you're trying to build reusable code that works for all types but I think you're really only saving one line in the child.  Something like:

id = Interlocked.Decrement(_tempId);

I assume you're using negative numbers like me as temporary ids which are replaced with the real identity id from SQL server or whatever when it's saved.

Wbmstrmjb:

Does anyone see a problem with adding the following to the extended base class for editable lists?  I would think that all lists would want the same default functionality for AddNew.

 

protected override object AddNewCore()

{

decimal id = this.Count + 1;

id *= -1;

C obj = null;

Type cType = typeof(C);

string newMethod = "New" + cType.Name;

obj = (C)cType.InvokeMember(

newMethod,

BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static,

null,

null,

new object[] { id });

this.Add(obj);

return obj;

}

Wbmstrmjb replied on Thursday, February 12, 2009

Good point with the delete and increment being out of sync.  But this code does far more than save 1 line in the child.  It is implementing the actual add.  The default AddNew does not work with internal methods which are what the child class has. 

RockfordLhotka replied on Thursday, February 12, 2009

It might be better to use the data portal:

protected override object AddNewCore()
{
  var item = DataPortal.CreateChild<C>();
  Add(item);
  return item;
}

I don't know if that would actually work, but it might. And it would follow standard child object creation, including allowing the child to intialize its own id value (or whatever) as necessary.

daniel_higgins replied on Thursday, February 12, 2009

I've been using guids lately, so I don't know, but ....

since the notion of equality has changed since csla was adopted for wpf, is it still neccessary to use negative int ids for new objects in collections?

tetranz replied on Thursday, February 12, 2009

I guess if you're not using the id for anything in your own code then no, you don't really need to assign anything to the id of a new item that hasn't been saved yet. You no longer have to override GetIdValue so CSLA of course doesn't care and has no way of knowing that your property called Id is anything special.

I tend to use int identities rather than Guids and still use negative numbers and update to the real id when saving. I also override GetIdValue because I have some generic methods in my base classes to GetItemById etc which I find myself using quite often.

daniel_higgins:

I've been using guids lately, so I don't know, but ....

since the notion of equality has changed since csla was adopted for wpf, is it still neccessary to use negative int ids for new objects in collections?

Copyright (c) Marimer LLC