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 PropertyAs 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!
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
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