Is it possible to restrict an object instance to just one other (parent) object in VB.NET?
VB 2008.NET 3.5
Suppose we have two classes, Order and OrderItem, which represent some kind of online ordering system. OrderItem represents one item in an order. One order can contain multiple instances of OrderItems as a list (OrderItem).
Public Class Order
Public Property MyOrderItems() as List(of OrderItem)
End Property
End Class
It makes sense that the OrderItem should not exist without an Order. In other words, the OrderItem class cannot be instantiated by itself, it must depend on the Order class in order to contain and create it. However, the OrderItem must be publicly visible in order for the properties to be available to other objects. Thus, the requirements for OrderItem are as follows:
-
Can only be created by the Order class.
-
Must be public so that any other object can access its properties / methods through the Order object. for example Order.OrderItem (0) .ProductID.
-
The OrderItem needs to be passed to other sub / functions that will work on it.
How can I achieve these goals? Is there a better approach?
a source to share
The standard way to do this is to expose OrderItem as an interface and then implement it in a private class inside the Order class. The OrderItem class can only be created inside the Order class, but it can be exposed from the outside through the general IOrderItem interface. For instance:
Public Interface IOrderItem
ReadOnly Property ItemCode() As Integer
ReadOnly Property NumberOfItems() As Integer
ReadOnly Property Description() As String
End Interface
Public Class Order
Private m_Items As List(Of IOrderItem)
Public ReadOnly Property Items() As List(Of IOrderItem)
Get
Return m_Items
End Get
End Property
Private Class OrderItem
Implements IOrderItem
Private m_Code As Integer
Private m_NumItems As Integer
Private m_Description As String
Public Sub New(ByVal code As Integer, ByVal numItems As Integer, ByVal desc As String)
m_Code = code
m_NumItems = numItems
m_Description = desc
End Sub
Public ReadOnly Property Description() As String Implements IOrderItem.Description
Get
Return m_Description
End Get
End Property
Public ReadOnly Property ItemCode() As Integer Implements IOrderItem.ItemCode
Get
Return m_Code
End Get
End Property
Public ReadOnly Property NumberOfItems() As Integer Implements IOrderItem.NumberOfItems
Get
Return m_NumItems
End Get
End Property
End Class
End Class
a source to share
You can create a single constructor OrderItem
that takes an element Order
.
In this constructor, you can add OrderItem
to the collection Order.MyOrderItems
.
It will meet your requirements.
Public Class OrderItem
Public Sub New(ByRef myOrder As Order)
myOrder.MyOrderItems.Add(Me)
End Sub
End Class
- You can only create an instance
OrderItem
by passing a valid object to itOrder
. - Publication and can be called on demand (
Order.OrderItem(0).ProductID
). - OrderItem can be passed to other submarines and functions.
a source to share
OrderItem
the constructor should be friend
(only accessible to Order
) - I say friend
because by using friend
, you can limit the visibility of the constructor to OrderItem
classes in the same assembly. Note : this solution assumes that Order and OrderItem are in the same library / assembly and you are trying to use them from a different assembly, otherwise the protection friend
will not work.
Responsibility for creating objects OrderItem
should belong only to Order
:
Create a method like the class Order
: Public Function CreateOrderItem(whateverParametersYouNeed) as OrderItem
that internally creates a new one OrderItem
, adds it to the list, OrderItem
and returns a reference to the newly created item.
Then you can do whatever you want with this OrderItem
- it will always belong to the list Order
.
a source to share