Aggregation relationships and instantiating objects from database storage (vb) - database

I have a small application which allows users to create accounts and then award 'points' to each other. UserAccount is an object, and so is Point, and there is an aggregation relationship between them: each UserAccount has a member variable (PointHistory) which is a collection of Points.
The Point object simply contains properties for which UserAccount object sent/received the Point.
This was fine when I simply serialized the classes to persist my object model. However, I am now implementing a database to persist the object data, and only one/some objects will be loaded into memory at any given time. To load the objects, I have a constructor method which creates a new UserAccount from a row in the database, and a similar constructor to create a Point from a database row. This is where the trouble starts - how can the constructor for one object call the constructor for another object when the second constructor must refer to what the first constructor has not yet constructed? In order to complete construction, the object must be already constructed.
The easy solution is simply to replace the collection of Point objects (PointHistory) with a collection of strings drawn from a database query. This suffices for my purposes. However, I'm wondering if there is another way to do that which doesn't abandon the Point object/object-model, and whether this aggregation/persistence problem is common?

If I understand correctly, the UserAccount constructor needs to construct the Points that belong to this UserAccount, and these Points need a way to refer to the UserAccount currently under construction?
If that is the case, you can pass Me into the Point constructor, which will in effect pass the UserAccount that's being constructed. It will pass the UserAccount object even it the construction hasn't yet completed.
Class UserAccount
Private _pointHistory As New System.Collections.Generic.List(Of MyProject.Point)
Public Sub New()
...
...
' Instantiate a new point, and pass this UserAccount object into it
' so that it can grab a reference
Dim newPoint as New MyProject.Point(Me)
'Add the Point to this UserAccount's collection
_pointHistory.Add(newPoint)
End Sub
End Class
Class Point
Private _parentAccount as MyProject.UserAccount
Public Sub New(parentAccount as MyProject.UserAccount)
'Store the reference to the User Account
_parentAccount = parentAccount
End Sub
End Class

Related

How do I save a reordered list back to the SQL Server?

Using EF6 and SQL Server. This question is to ask if I am going in the right direction with my code.
Using a variety of SO posts I was able to define classes that contain lists and incorporate IComparable(Of T). Although the objects in the lists have properties that can be used for ordering such as dates, I need to maintain a user-defined order that is solely determined by how the user wants the objects arranged.
My first assumption is that I have to maintain a distinct property to maintain the user-defined order. Is that correct? This is a very simplified example of what I currently have defined:
Class Parent
:
Public Property SomeList as List(Of Something)
End Class
Class Something
Implements IComparable(of Something)
:
public property PositionInList as Integer
Public Function CompareTo(that As Something) As Integer ...
Return PositionInList.CompareTo(that.PositionInList)
End Function
End Class
And if I write the following:
dim aList as New List(Of Something)
aList = Parent.SomeList
aList.Sort()
...alist is sorted based on PositionInList as I expected.
If I want to insert a new record into the list, am I responsible for changing the values of PositionInList throughout all the objects in the list? The reason I ask is because the LINQ command of the form .insert(index,object) indicates it inserts an element into the List(Of T) at the specified index. And as I look at the table after the .insert(index,object) prior to SaveChanges(), the list does have the new object in the correct location, but it didn't set PositionInList to the value of the index specified in .insert(index,object). Is it supposed to and I haven't coded things correctly? Also, PositionInList is going to have to ripple the change throughout all the objects - am I responsible for that?
Are there predefined methods I need to learn that would manipulate PositionInList when I insert?
I will also want the user to be able to move items to new positions in the lists. Are there patterns to do this kind of thing, or once again is that pretty much up to me?
Added per request in comment below:
The application is divided into 3 layers: UI, domain, storage. The storage layer includes a storage service class which has the CRUD methods that interface to the SQL Server.
This is one of the current Create methods. At present it only appends a record at the end of the list. Per your comment, I will modify it to update PositionInList when the call to create requests an insertion somewhere inside the list. That will require additional parameters not currently coded in the method.
Public Overrides Sub ElementCreate(DomainElement As DomainElement)
Dim aSqlElement As New SqlElement
aSqlElement.DomainToSqlElement(DomainElement)
Dim theParent = SqlContext.SqlContents.Include("ContentElements").Where(Function(x) x.ID = aSqlElement.ContentID).SingleOrDefault()
theParent.ContentElements.Add(aSqlElement)
SqlContext.SaveChanges()
End Sub
You can use a SortedSet instead so that you don't have to re-sort.
Class Parent
:
Public SortedSet<Something> SomeList = new SortedSet<Something>(
new FuncComparer<Something>( (a, b) => a.PositionInList.CompareTo(b.PositionInList ) ));
End Class

What is the best way to manage certain traits of objects in an array?

I'm using an array for objects that are performing a hitTest on another object, called Chest. Basically I want to drag the array objects into the chest, and when a certain object is in the chest certain functions will run. So to go about it I want to assign each object a "touching" property that is false by default, and true if the array object is touching/"in" the chest, but I'm not sure how.
I'm new to action/javascript and I've heard you can pretty much assign whatever properties you want to any object, but I'm not sure how to go about that and how the properties would be managed.
To add to this, how could I keep track of how many objects in the array are touching the chest?
Any explanations with or without example code would be greatly appreciated!
Create a class of the object you want to hittest.(for example, Test)
Add checkHit property or some thing like that.
class Test extends MovieClip
{
public var checkHit:Boolean=false;
}
In Root class,
push every object into an array.
testArray.push(new Test());
Now,
You can check hit in EnterFrame event with a loop.
for(var i:int=0;i<testArray.length;i++)
{
if(testArray[i].hitTestObject(chest))
{
testArray[i].checkhit=true;
/// prefrom your code.
}
}
If you want to check no. of objects hitting chest. you can use a global variable.
for(var i:int=0;i<testArray.length;i++)
{
if(testArray[i].hitTestObject(chest))
{
testArray[i].checkhit=true;
hitCount++;
/// prefrom your code.
}
}

How can I populate an instance of an object with random values?

Is there any way I can give AutoFixture an instance of an object and have it go through all the setters and set random data? The wiki examples only show how to obtain an instance from AutoFixture, e.g.
var autoGeneratedClass = fixture.Create<ComplexParent>();
My example use case is a factory method which generate instances of objects with dynamic properties based on a configuration. I want to test that my methods correctly, detect and interact (e.g. copy) these dynamic properties.
dynamic dynamicPropertyObject1 = factoryMethod(configuration);
dynamic dynamicPropertyObject2 = factoryMethod(configuration);
dynamicPropertyObject1.propA = random.Next();
dynamicPropertyObject1.CopyTo(dynamicPropertyObject2);
Assert.That(dynamicPropertyObject2.propA, Is.EqualTo(dynamicPropertyObject1.propA);
Thanks
AutoFixture has a lot of built-in heuristics for creating objects, including some for factory methods.
If AutoFixture finds no public constructors on a type, it starts to look for factory methods; i.e. static methods that return objects of the type of the class that defines that static method, e.g.
public class Foo
{
public static Foo CreateFoo();
// ... other members
}
If, on the other hand, a factory method exists on another class, you'll need to help AutoFixture a bit. The easiest way would be to use the Customize method:
fixture.Customize<Foo>(c => c
.FromFactory(() => FooFactory.CreateFoo())
.WithAutoProperties());
When you subsequently ask a Fixture object for a Foo object, FooFactory.CreateFoo() will be invoked, and because of WithAutoProperties that object will be populated with data created by AutoFixture.

In VB 2008, how can one subprocedure accept different arrays of a structure in different calls?

I'm writing a character creator for my friend's tabletop RPG using Visual Basic 2008 as a learning exercise so please be kind if I've made stupid choices. :]
I have three arrays of a structure, one called m_OwnedWeapons that's created from a structure called Weapons, one called m_OwnedArmor created from a structure called Armor, and one called m_OwnedPotions created from a structure called Potions. They have some similarities and several differences but a lot of the time I need to do an identical operation on each of them. For example, when the index in a listbox changes, my program searches through each of these arrays of a structure to find which holds the item and then it updates the displayed values (cost, description, etc).
My problem is that I'd like a way that I only have to write the search code one time. Right now I have to write it three times because it has to search each by name. I have this same code posted three times, only once it refers to m_OwnedPotions, once it refers to m_OwnedArmor, and once it refers to m_Owned Weapons:
LoopCountInteger = 0
If m_OwnedPotionsCounterInteger > 0 Then
Do Until LoopCountInteger >= m_OwnedPotionsCounterInteger Or ItemFoundBoolean = True
If InventoryListBox.SelectedItem.Equals(m_OwnedPotions(LoopCountInteger).NameString) Then
ItemFoundBoolean = True
End If
LoopCountInteger += 1
Loop
End If
Is there a way to maybe write some kind of subprocedure with this code that accepts the array of a structure name as its parameter? Is this not possible because one is an array of a structure of Weapons, one of Armor, and one of Items?
Maybe I just need one array of a structure called Items that will hold the fields required by all item types, but if I do it that way it seemed untidy because that one structure had so many fields unused for most items. I don't know.
Thanks for any help and suggestions.
So solving this type of problem is normally done through inheritance. You have three different types of objects that share some basic properties but are also different things. To represent these objects in your code, create a base class that will hold their common properties (name, cost, description, etc.) and a subclass for each of the more concrete types.
Here is one sort of exammple:
Public Class Equipment
Public Name As String
Public Desc As String
Public Cost As Integer
Public Weight As Integer
End Class
Public Class Weapon
Inherits Equipment
Public MinimumDamage As Integer
Public MaximumDamage As Integer
Public Speed As Integer
End Class
Public Class Potion
Inherits Equipment
Public Effect As String
End Class
Public Class Armor
Inherits Equipment
Public SpeedPenalty As Integer
Public ArmorClass As Integer
End Class
Now, using polymorphism you can write procedures that can operate on any of these items by accepting a parameter of the base type. Your program can also have a container that holds all of the equipment so you only have to search one list to find the object that is selected.

C# - Pass a struct to a form by reference and return value?

I have a struct:
struct Order
{
public string orderNumber;
public string orderDetail;
}
I then assign some values in Form1 and try to pass them by reference (ref) to Form2:
(Form1)
Order order = new Order();
order.orderNumber = "1234";
order.orderDetail = "Widgets";
Form2 frm2 = new Form2(ref order);
Is it possible to store the values in Form2 so that when Form2 is completed processing the values it will return the updated struct values to Form1?
In this scenario there would be a button that would close the form after validating the data.
One pattern that's sometimes useful is to define a class something like:
class Holder<T> {public T value;}
Such a class makes it possible to pass and mutate value types with code that requires reference types. Using such an approach, a routine which accepted a structure by reference and was supposed to pop up a modal dialog and fill in the structure from it, could create a Holder<thatStructType>, pass that to the form, and then copy the data from that Holder back to the passed-in reference. While in your particular scenario, it may be better to have the data-holding thing simply be a class, structures have the advantage that one can know that no outstanding references to them exist; if a routine declares a structure and passes it by reference to some outside code, then once that code returns the values in that structure won't change unless or until the routine writes them itself or passes the structure by reference to some other code. By contrast, if a routine exposes a class reference to outside code, there's no telling what that code may do with it.
Incidentally, the Holder class is also useful in a number of other scenarios. For example, if one has a Dictionary<String, Holder<Integer>> myDict, one may use Threading.Interlocked.Increment(myDict(myKey).Value)) to perform a thread-safe increment of the indicated item, much more efficiently than would be possible with a Dictionary<String, Integer>.
What I think you're asking is if Form2 can store a reference to the order structure that was passed in the constructor. The answer is no. If you want to store references, use a reference type (a class).

Resources