Help with Interface implementation for Child Collections

Help with Interface implementation for Child Collections

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


NightOwl888 posted on Monday, April 28, 2008

I have been struggling with trying to find a way for a common piece of code to walk through similar child collections of different root objects.

I have 2 root objects that are derived from the same base as follows:

ItemBase

   ShoppingCartItem

   OrderItem

Each of the subclasses contains a child collection of objects derived from ItemAttributeBase, ShoppingCartItemAttribute and OrderItemAttribute respectively.

What I am trying to accomplish is making the same piece of code access the objects in both collections by passing a reference to ItemBase.

To accomplish this, I have created an interface for my ShoppingCartItemAttributeCollection and OrderItemAttributeCollection objects called IItemAttributeCollection. This interface exposes a special overload of the Item property that returns an object of type ItemAttributeBase.

The implementation of my properties for accessing both Attribute collections look like this:

Public ReadOnly Property Attributes() As ShoppingCartItemAttributeCollection

Get

Return mAttributes

End Get

End Property

Friend Overrides ReadOnly Property AttributeCollection() As IItemAttributeCollection

Get

Return mAttributes

End Get

End Property

As you can see, they both return the same reference to my attribute collection. However, I have run into an issue where when I try to access the collection through this AttributeCollection() property, it doesn't return a populated object. Here is my code that tries to access the collection:

Item.AttributeCollection(AttributeCategoryEnum.Height)

This returns a reference to the attribute object that represents "height" so my business logic can tell it apart from the other attribute objects. However, it although it returns an instance of the object, it is not the same instance that I updated with my code. This next line of code does function:

CType(Item, ShoppingCartItem).Attributes(3)

This is passing "3" as the attribute id (key) of the same object. The object reference I get back from this line contains an instance of the object that is populated with the values that I put there.

So, although I am returning a pointer to the same collection through my properties, I am not receiving the same collection for my code to use. I have stepped through this code several times and I always get the same results. I know for certain there is nothing wrong with my Item properties - the entire collection I am getting back has "new" object references in it.

I am not saying this approach is perfect, but I would like to know exacly how I can structure my child collections so I can walk through both of them using the same business rules code. Please help!

JoeFallon1 replied on Tuesday, April 29, 2008

It sounds to me like the wrong overload is being called.

You *think* you are calling Item.AttributeCollection(Enum.Height) which is your new overload. But in reality it is calling the standard (index) instead.

Always be careful when overloading a single numeric parameter.

Try adding a 2nd parameter like myDummyParam As Boolean to your method and then ignore the 2nd parameter in the method. But when you call it, pass the 2nd param in (T or F - it won't matter.) Then step through your code and see if it is working correctly and calling the correct overloaded method.

Joe

 

NightOwl888 replied on Tuesday, April 29, 2008

Thanks for the help Joe.

Actually, this is not the case. I have confirmed that it is a type casting problem, but for the life of me I can't figure out why. I stepped all the way through the code and confirmed the right overload was being called - the problem was that the overload was being called on another "ghost" copy of the collection that wasn't the same copy that my UI code was updating.

If the wrong indexer was being used, I would have received the wrong object - but I am getting an object with the correct AttributeID, but all of the other properties are blank. The object I received was in the same state it would have been after calling the "create" method on the collection. However, I confirmed that the object I was looking for also exists in memory by casting to the correct root type first.

For the time being I got around this problem by passing both an instance of ItemBase AND an object that conforms with my IItemAttributeCollection interface into my function. While not the most elegant solution, it at least gives me the ability to step through the objects without knowing exactly which type they are.

However, if there are any other suggestions please post them. I will be revisiting this issue when I upgrade my framework to CSLA 2.0.

 

 

Copyright (c) Marimer LLC