Search code examples
vb.netsharedaccess-modifiersgeneric-list

Problem Understanding Access Modifiers in VB.Net with List( Of Object)


I've recently been updating a lot of my code to comply with proper n-tier architecture and OO programming, following examples from a book.

I'm starting to get problems now because I don't fully understand the access modifiers.

If I run the following code I get an error at the line

Dim clientFamilyDataAccessLayer As New ClientFamilyDAO

in the BLL at the point it creates an instance of the DAL. The full error message is: "The type initializer for 'ClientFamilyDAO' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object."

How do I use these function to create a list of ClientFamily objects that I can then work with?

On my UI layer I'm creating a list of objects; ClientFamilies

Dim listOfClientFamilies As List(Of ClientFamily) = ClientFamily.GetClientFamiliesByKRM(selectedEmployee.StaffNumber)

This is the function in the BLL

Public Shared Function GetClientFamiliesByKRM(ByVal krmStaffNumber As Integer) As List(Of ClientFamily)

        Dim clientFamilyDataAccessLayer As New ClientFamilyDAO
        Return clientFamilyDataAccessLayer.GetClientFamiliesByKRM(krmStaffNumber)

    End Function

and this is function in the DAL

Public Function GetClientFamiliesByKRM(ByVal staffNumber As Integer) As List(Of ClientFamily)

        Dim currentConnection As SqlConnection = New SqlConnection(_connectionString)

        Dim currentCommand As New SqlCommand
        currentCommand.CommandText = mainSelectStatement & " WHERE Key_Relationship_Manager = @StaffNumber ORDER BY Client_Family_Name"
        currentCommand.Parameters.AddWithValue("@StaffNumber", staffNumber)
        currentCommand.Connection = currentConnection

        Dim listOfClientFamilies As New List(Of ClientFamily)

        Using currentConnection

            currentConnection.Open()

            Dim currentDataReader As SqlDataReader = currentCommand.ExecuteReader()

            Do While currentDataReader.Read

                Dim newClientFamily As AECOM.ClientFamily = PopulateClientFamily(currentDataReader)

                listOfClientFamilies.Add(newClientFamily)

            Loop

        End Using

        Return listOfClientFamilies

    End Function

Here's the full ClientFamilyDAO Class:

    Public Class ClientFamilyDAO

    Private Const mainSelectStatement As String = "SELECT Client_Family_ID, Client_Family_Name, Key_Relationship_Organisation, Key_Relationship_Manager, Obsolete, Market_Sector_ID FROM Client_Families"

    Private Shared ReadOnly _connectionString As String = String.Empty

    Shared Sub New()

        _connectionString = WebConfigurationManager.ConnectionStrings("ClientFamilyManagementConnectionString").ConnectionString

    End Sub

    Public Function GetClientFamiliesByKRM(ByVal staffNumber As Integer) As List(Of ClientFamily)

        Dim currentConnection As SqlConnection = New SqlConnection(_connectionString)

        Dim currentCommand As New SqlCommand
        currentCommand.CommandText = mainSelectStatement & " WHERE Key_Relationship_Manager = @StaffNumber ORDER BY Client_Family_Name"
        currentCommand.Parameters.AddWithValue("@StaffNumber", staffNumber)
        currentCommand.Connection = currentConnection

        Dim listOfClientFamilies As New List(Of ClientFamily)

        Using currentConnection

            currentConnection.Open()

            Dim currentDataReader As SqlDataReader = currentCommand.ExecuteReader()

            Do While currentDataReader.Read

                Dim newClientFamily As AECOM.ClientFamily = PopulateClientFamily(currentDataReader)

                listOfClientFamilies.Add(newClientFamily)

            Loop

        End Using

        Return listOfClientFamilies

    End Function

    Private Function PopulateClientFamily(ByVal currentDataReader As SqlDataReader) As AECOM.ClientFamily

        Dim newClientFamily As New AECOM.ClientFamily

        If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Client_Family_ID"))) Then
            newClientFamily.ClientFamilyID = currentDataReader("Client_Family_ID")
        End If

        If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Client_Family_Name"))) Then
            newClientFamily.ClientFamilyName = currentDataReader("Client_Family_Name")
        End If

        If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Key_Relationship_Organisation"))) Then
            Select Case currentDataReader("Key_Relationship_Organisation")
                Case False
                    newClientFamily.IsKeyRelationshipOrganisation = False
                Case True
                    newClientFamily.IsKeyRelationshipOrganisation = True
            End Select
        End If

        If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Key_Relationship_Manager"))) Then
            newClientFamily.KeyRelationshipManagerStaffNumber = currentDataReader("Key_Relationship_Manager")
        End If

        If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Obsolete"))) Then
            Select Case currentDataReader("Obsolete")
                Case False
                    newClientFamily.Obsolete = False
                Case True
                    newClientFamily.Obsolete = True
            End Select
        End If

        If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Market_Sector_ID"))) Then
            newClientFamily.MarketSectorID = currentDataReader("Market_Sector_ID")
        End If

        Return newClientFamily

    End Function

End Class

Solution

  • The issue doesn't relate to access modifiers, rather it is more to do with the exception message you get. The following line within the constructor of ClientFamilyDAO would seem to be causing the issue:

    _connectionString = WebConfigurationManager.ConnectionStrings("ClientFamilyManagementConnectionString").ConnectionString
    

    Are you sure ClientFamilyManagementConnectionString exists in the configuration?