views:

57

answers:

3

I don't know really how to word the question so please bear with me...

I have 3 classes: Server, Database, and Table. Each class has a "Name" property. How I want it to work is that each server can have multiple databases and each database can have multiple tables. So in the Server class I have this property.

Private _databases As List(Of Database)
Public Property Databases() As List(Of Database)
    Get
        Return _databases
    End Get
    Set(ByVal value As List(Of Database))
        _databases = value
    End Set
End Property

And I have something similar in the Database class for the tables. This works fine now because I can do something like this to get all the databases in the server.

For Each db In s.Databases 's being the server object
        Debug.Print(db.Name)

    Next

I would like to expand these classes. I want the server class to handle all the connection information and I would like the other classes to use the server class's connection information in them.

For example, I setup a server class and set the connection string to the server. Then I want the database class to use serverclass.connectionstring property to connect to the server and get a list of all the databases. But I want to keep that code in the database class. How can I do this?

I've attached some code of what I want to do.

Public Class Server

Private _name As String
Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal value As String)
        _name = value
    End Set
End Property


Private _databases As List(Of Database)
Public Property Databases() As List(Of Database)
    Get
        Return _databases
    End Get
    Set(ByVal value As List(Of Database))
        _databases = value
    End Set
End Property
End Class

'-----New class  

Public Class Database

Private _name As String
Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal value As String)
        _name = value
    End Set
End Property


Private _tables As List(Of Table)
Public Property Tables() As List(Of Table)
    Get
        Return _tables
    End Get
    Set(ByVal value As List(Of Table))
        _tables = value
    End Set
End Property

'This is where I need help!
Private Sub LoadTables () 
    dim connectionstring as string = server.connectionstring 'Possible?

    'Do database stuff
End Class

Thanks for reading!

+1  A: 

Pass the Server to the Database when constructing it, and set a field. This is a very basic form of dependency injection.

Matthew Flaschen
+1 for the link and what it is called. I'm always looking to learn more!
Clint Davis
+2  A: 

You'll have to include a reference to the "owner" class in your child class.

Without using code (for the sake of brevity), you have right now

Server
----------
Databases   -----> Database
Name               ------------
                   Tables       -----> Table
                   Name                --------------
                                       Name

What you want is something like this:

Server
----------
Databases   -----> Database
Name               ------------
  ^                Tables       -----> Table
  |                Name                --------------
   --------------- Server              Name
                     ^                 Database
                     |-------------------|

The Server property on the Database class and the Database property on the Table class are intended to be references to the instance of each that owns them.

Adam Robinson
Thanks this is what I wanted to do.
Clint Davis
+1  A: 

I would personnaly make the database aware of the server on which it is stored, so that the database would know where to connect depending the the server it is given.

Doing so would look something like:

public class Database {
    public Database(Server server) {
        Server = server;
    }

    public Server Server { get; private set; }
}
Will Marcouiller
+1 for the code. It helped me on my way.
Clint Davis
Thanks for letting me know I have brought you something. This is kind. =)
Will Marcouiller