Results 1 to 19 of 19

Thread: Can't Access Properties Of Declared Instance Of A Class

  1. #1

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Can't Access Properties Of Declared Instance Of A Class

    Hi Guys,

    I have run into an odd situation that I can't seem to make sense of. I have a solution consisting of two projects, Project 1 is my DAL. This project contains 1 class module and contains functions that will be used as the Data Access Layer for my app. Project 2 is my BLL. The BLL consists of one class module per table and has public properties for each field in that table. The class modules are declared public. The BLL has a reference to the DAL and each class module has an Inherits statement referencing the DAL. The DAL is declared MustInherit. I am at a point where I wanted to do some simple tests so I created module in the BLL project. I dimmed a variable as a new instance of one of my classes and then attempted to access the properties of that instance and I couldn't. I get a syntax error saying declaration expected. No properties are displayed for the new instance of the class. Have also tried using a class module and a completely separate project with a reference to the BLL. I get the same result. Not sure what the deal is. Am not sure what code I should post to help resolve the issue. Not sure what I'm doing wrong. I know I am missing something but don't know what it is. Any help you can provide is appreciated.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Can't Access Properties Of Declared Instance Of A Class

    There's a problem with your code but you chose not to show us that code? That's not the way to get help. ALWAYS show us the relevant code.

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Can't Access Properties Of Declared Instance Of A Class

    Just a quibble: You mention class modules a couple times. In VB, a Module is a special type of class that doesn't really look like a class (though it is). So, you might just say class when you mean class and module when you mean module. Since they have some distinct behaviors, if you are actually talking about modules, that would likely change any answer.

    In this case, I somewhat disagree with JMC. There are a few things that would be somewhat good to see in the code, such as how you declare the variable that isn't showing you anything. However, I'm kind of leaning towards you not having the DAL project properly referenced by the BLL project, which would be pretty hard to show. How did you reference the one project from the other?
    My usual boring signature: Nothing

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Can't Access Properties Of Declared Instance Of A Class

    Quote Originally Posted by Shaggy Hiker View Post
    In this case, I somewhat disagree with JMC. There are a few things that would be somewhat good to see in the code, such as how you declare the variable that isn't showing you anything. However, I'm kind of leaning towards you not having the DAL project properly referenced by the BLL project, which would be pretty hard to show.
    The OP reported a syntax error and an error message that indicates that a declaration is expected. A bad/missing reference wouldn't cause that. You'd expect a message about an inaccessible type or the like. A syntax error is always an issue with the code.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Can't Access Properties Of Declared Instance Of A Class

    I felt there was enough fuzziness in the description that I wasn't confident about that being the source the error.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    Thanks Guys and I get your point. It is hard to figure out the problem without seeing the code. In answer to the question about the reference. I added a reference in the BLL project to the DAL project no import statement in the class module. Here's the code for the DAL Class.
    Code:
    Imports System.Data.Common
    Imports System.Configuration
    Public MustInherit Class DAL
        ' Private Variables
        Private _DataProviderName As String
        Private _Factory As DbProviderFactory
        Private _ConnectionString As String
        Protected _Connection As DbConnection
        Protected _Transactionn As DbTransaction
        ' Properties
        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
        ' Protected property that exposes the connection string to inheriting
        ' classes. Read-Only.
        Public Property DataProviderName() As String
            Get
                Return _DataProviderName
            End Get
            Set(ByVal value As String)
                _DataProviderName = value
                FoundProvider(_DataProviderName)
            End Set
        End Property
        Public ReadOnly Property ProviderFactory As DbProviderFactory
            Get
                Return _Factory
            End Get
        End Property
        Protected ReadOnly Property ConnectionString() As String
            Get
                Return _ConnectionString
            End Get
        End Property
        Public ReadOnly Property Connection As DbConnection
            Get
                Return _Connection
            End Get
        End Property
        Public ReadOnly Property Transaction As DbTransaction
            Get
                Return _Transactionn
            End Get
        End Property
        ' Constructors
        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        Public Sub New()
    
            MyBase.New()
    
        End Sub
        ' A parameterized constructor, it allows us to take a connection string
        ' as a constructor argument, automatically instantiating a new connection
        ' ---
        Public Sub New(ByVal dataProvidername As String)
    
            MyBase.New()
            If FoundProvider(dataProvidername) Then
                _Connection = CreateDbConnection(dataProvidername)
            Else
            End If
    
        End Sub
        ' Methods
        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        ' Runs a stored procedure, can only be called by those classes deriving
        ' from this base. It returns an integer indicating the return value of the
        ' stored procedure, and also returns the value of the RowsAffected aspect
        ' of the stored procedure that is returned by the ExecuteNonQuery method.
        Protected Function ReturnResult(ByVal storedProcName As String, ByVal parameters As IDataParameter(), ByRef rowsAffected As Integer) As Integer
    
            Dim result_ As Integer
            Dim command_ As DbCommand = _Factory.CreateCommand()
            Dim internalOpen As Boolean = False
    
            Try
                command_ = BuildIntCommand(storedProcName, parameters)
                If _Connection.State = ConnectionState.Closed Then
                    _Connection.Open()
                    internalOpen = True
                End If
                rowsAffected = command_.ExecuteNonQuery()
                result_ = CInt(command_.Parameters("ReturnValue").Value)
                _Connection.Close()
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            Finally
                If internalOpen Then _Connection.Close()
            End Try
    
            Return result_
    
        End Function
        ' Will run a stored procedure, can only be called by those classes
        ' deriving from this base. It returns a SqlDataReader containing the
        ' result of the stored procedure.
        Protected Function ReturnDataReader(ByVal storedProcName As String, ByVal parameters As IDataParameter()) As DbDataReader
    
            Dim command_ As DbCommand = _Factory.CreateCommand()
            Dim reader_ As DbDataReader
            Dim internalOpen As Boolean = False
    
            Try
                command_ = BuildQueryCommand(storedProcName, parameters)
                If _Connection.State = ConnectionState.Closed Then
                    _Connection.Open()
                    internalOpen = True
                End If
                reader_ = command_.ExecuteReader(CommandBehavior.CloseConnection)
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            Finally
                If internalOpen Then _Connection.Close()
            End Try
    
            Return reader_
    
        End Function
        ' Creates a DataSet by running the stored procedure and placing
        ' the results of the query/proc into the given tablename.
        Protected Function ReturnDataset(ByVal storedProcName As String, ByVal parameters As IDataParameter(), ByVal tableName As String) As DataSet
    
            Dim dataSet_ As New DataSet()
            Dim dataAdapter_ As DbDataAdapter = _Factory.CreateDataAdapter
            Dim internalOpen As Boolean = False
    
            Try
                If _Connection.State = ConnectionState.Closed Then
                    _Connection.Open()
                    internalOpen = True
                End If
                dataAdapter_.SelectCommand = BuildQueryCommand(storedProcName, parameters)
                dataAdapter_.Fill(dataSet_, tableName)
                _Connection.Close()
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            Finally
                If internalOpen Then _Connection.Close()
            End Try
    
            Return dataSet_
    
        End Function
        Protected Function ReturnScalar(ByVal storedProcName As String, ByVal parameters As IDataParameter()) As Object
    
            Dim result_ As Object
            Dim command_ As DbCommand = _Factory.CreateCommand()
            Dim internalOpen As Boolean = False
    
            Try
                command_ = BuildIntCommand(storedProcName, parameters)
                If _Connection.State = ConnectionState.Closed Then
                    _Connection.Open()
                    internalOpen = True
                End If
                result_ = command_.ExecuteScalar
                _Connection.Close()
                If result_ Is DBNull.Value Then
                    Return Nothing
                Else
                    Return result_
                End If
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            Finally
                If internalOpen Then _Connection.Close()
            End Try
    
            Return result_
    
        End Function
        ' Takes an -existing- dataset and fills the given table name
        ' with the results of the stored procedure.
        Protected Sub FillTable(ByVal storedProcName As String, ByVal parameters As IDataParameter(), ByVal dataSet As DataSet, ByVal tableName As String)
    
            Dim dataAdapter_ As DbDataAdapter = _Factory.CreateDataAdapter
            Dim internalOpen As Boolean = False
    
            Try
                If _Connection.State = ConnectionState.Closed Then
                    _Connection.Open()
                    internalOpen = True
                End If
                dataAdapter_.SelectCommand = BuildIntCommand(storedProcName, parameters)
                dataAdapter_.Fill(dataSet, tableName)
                _Connection.Close()
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            Finally
                If internalOpen Then _Connection.Close()
            End Try
    
        End Sub
        Public Function BeginTransaction() As Boolean
    
            If _Connection IsNot Nothing AndAlso _Connection.State = ConnectionState.Closed AndAlso _Transactionn Is Nothing Then
                _Connection.Open()
                _Transactionn = CType(_Connection.BeginTransaction(), DbTransaction)
                Return True
            End If
    
            Return False
    
        End Function
        Public Function RollBackTransaction() As Boolean
    
            If _Connection IsNot Nothing AndAlso _Connection.State = ConnectionState.Open AndAlso _Transactionn IsNot Nothing Then
                _Transactionn.Rollback()
                _Connection.Close()
                _Transactionn.Dispose()
                Return True
            End If
    
            Return False
    
        End Function
        Public Function CommitTransaction() As Boolean
    
            If _Connection IsNot Nothing AndAlso _Connection.State = ConnectionState.Open AndAlso _Transactionn IsNot Nothing Then
                _Transactionn.Commit()
                _Connection.Close()
                _Transactionn.Dispose()
                Return True
            End If
    
            Return False
    
        End Function
        ' Private Code
        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
        ' Private routine allowed only by this base class, it automates the task
        ' of building a SqlCommand object designed to obtain a return value from
        ' the stored procedure.
        Private Function BuildIntCommand(ByVal storedProcName As String, ByVal parameters As IDataParameter()) As DbCommand
    
            Dim command_ As DbCommand = _Connection.CreateCommand
            Dim parameter_ As DbParameter = _Factory.CreateParameter
    
            Try
                command_ = BuildQueryCommand(storedProcName, parameters)
                With parameter_
                    .ParameterName = "ReturnValue"
                    .DbType = SqlDbType.Int
                    .Size = 4
                    .Direction = ParameterDirection.ReturnValue
                    .IsNullable = False
                    .Precision = 0
                    .Scale = 0
                    .SourceColumn = String.Empty
                    .SourceVersion = DataRowVersion.Default
                    .Value = Nothing
                End With
                command_.Parameters.Add(parameter_)
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            End Try
    
            Return command_
    
        End Function
        ' Builds a SqlCommand designed to return a SqlDataReader,
        ' and not an actual integer value.
        Private Function BuildQueryCommand(ByVal storedProcName As String, ByVal parameters As IDataParameter()) As DbCommand
    
            Dim command_ As DbCommand = _Connection.CreateCommand()
            Dim parameter_ As DbParameter = _Factory.CreateParameter
    
            Try
                command_.CommandType = CommandType.StoredProcedure
                If _Transactionn IsNot Nothing Then
                    command_.Transaction = _Transactionn
                Else
                    command_.Connection = _Connection
                End If
                For Each parameter_ In parameters
                    command_.Parameters.Add(parameter_)
                Next
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            End Try
    
            Return command_
    
        End Function
        Private Function FoundProvider(dataProvidername As String) As Boolean
    
            Try
                _Factory = DbProviderFactories.GetFactory(dataProvidername)
                If _Factory IsNot Nothing Then
                    CreateDbConnection(dataProvidername)
                    FoundProvider = vbTrue
                Else
                    FoundProvider = vbFalse
                End If
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            End Try
    
            Return FoundProvider
    
        End Function
        ' Given a provider, create a DbConnection.
        ' Returns a DbConnection on success; Nothing on failure.
        Private Function CreateDbConnection(ByVal providerName As String) As DbConnection
    
            Dim connection_ As DbConnection = Nothing
    
            Try
                connection_ = _Factory.CreateConnection()
                connection_.ConnectionString = CreateDbConnectionString()
            Catch DbEx As DbException
                Throw DbEx
            Catch ex As Exception
                Throw ex
            End Try
    
            Return connection_
    
        End Function
        Private Function CreateDbConnectionString() As String
    
            Dim builder_ As DbConnectionStringBuilder = _Factory.CreateConnectionStringBuilder()
    
            builder_.Add("Data Source", "CURTIS-DESKTOP\SQLEXPRESS2016")
            builder_.Add("Initial Catalog", "MediaData")
            builder_.Add("integrated security", True)
    
            Return builder_.ConnectionString
    
        End Function
        Public Sub Dispose()
    
            Static Disposed As Boolean = False
    
            If (Disposed) Then
                Exit Sub
            End If
            Disposed = True
            _Connection.Dispose()
            _Transactionn.Dispose()
    
        End Sub
        Protected Overrides Sub Finalize()
    
            Dispose()
            MyBase.Finalize()
    
        End Sub
    
    End Class
    Here's the code from a class module in the BLL
    Code:
    Imports System.Data.SqlClient
    Public Class AlbumType
    
        Inherits DAL.DAL
    
        Private _AlbumTypeID As String
        Private _Description As String
        Private _DataProviderName As String
    
        Public Property AlbumTypeID() As String
            Get
                Return _AlbumTypeID
            End Get
            Set(ByVal value As String)
                _AlbumTypeID = value
            End Set
        End Property
        Public Property Description() As String
            Get
                Return _Description
            End Get
            Set(ByVal value As String)
                _Description = value
            End Set
        End Property
        Public Overloads Property DataProviderName() As String
            Get
                Return _DataProviderName
            End Get
            Set(ByVal value As String)
                _DataProviderName = value
                MyBase.DataProviderName = _DataProviderName
            End Set
        End Property
        Public Sub New()
    
            MyBase.New()
    
        End Sub
        Sub New(ByVal AlbumTypeID_ As String, ByVal Description_ As String)
    
            MyBase.New()
            AlbumTypeID = AlbumTypeID_
            Description = Description_
    
        End Sub
        Public Function Add(ByVal key As String, ByVal description As String) As Integer
    
            Dim rowsAffected As Integer
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            ' Create the parameters
    
            ' Set the values
            parameters(0).ParameterName = "@AlbumTypeID"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 4
            parameters(0).Value = key
            parameters(0).Direction = ParameterDirection.Input
    
            parameters(1).ParameterName = "@Description"
            parameters(1).SqlDbType = SqlDbType.VarChar
            parameters(1).Size = 20
            parameters(1).Value = description
            parameters(1).Direction = ParameterDirection.Input
    
            parameters(2).Direction = ParameterDirection.Output
    
            ' Run the procedure
            ReturnResult("inslkpAlbumType", parameters, rowsAffected)
    
            Return CInt(parameters(2).Value)
    
        End Function
        Public Function DeleteAlbumTypes() As Integer
    
            Dim rowsAffected As Integer
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).Direction = ParameterDirection.Output
    
            ReturnResult("dellkpAlbumTypeByKey", parameters, rowsAffected)
    
            Return CInt(parameters(0).Value)
    
    
        End Function
        Public Function DeleteAlbumTypeByKey(ByVal key As String) As Integer
    
            Dim rowsAffected As Integer
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).ParameterName = "@Original_AlbumTypeID"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 4
            parameters(0).Value = key
            parameters(0).Direction = ParameterDirection.Input
    
            parameters(1).Direction = ParameterDirection.Output
    
            ReturnResult("dellkpAlbumType", parameters, rowsAffected)
    
            Return CInt(parameters(1).Value)
    
    
        End Function
        Public Function DeleteAlbumTypeByDescruption(ByVal description As String) As Integer
    
            Dim rowsAffected As Integer
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).ParameterName = "@Original_Description"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 20
            parameters(0).Value = description
            parameters(0).Direction = ParameterDirection.Input
    
            parameters(1).Direction = ParameterDirection.Output
    
            ReturnResult("dellkpAlbumType", parameters, rowsAffected)
    
            Return CInt(parameters(1).Value)
    
    
        End Function
        Public Function UpdateAlbumTypeByKey(ByVal NewID As String, ByVal NewDescription As String, ByVal key As String) As Integer
    
            Dim rowsAffected As Integer
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).ParameterName = "@AlbumTypeID"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 4
            parameters(0).Value = NewID
            parameters(0).Direction = ParameterDirection.Input
    
            parameters(1).ParameterName = "@Description"
            parameters(1).SqlDbType = SqlDbType.VarChar
            parameters(1).Size = 20
            parameters(1).Value = NewDescription
            parameters(1).Direction = ParameterDirection.Input
    
            parameters(2).ParameterName = "@Original_AlbumTypeID"
            parameters(2).SqlDbType = SqlDbType.VarChar
            parameters(2).Size = 4
            parameters(2).Value = key
            parameters(2).Direction = ParameterDirection.Input
    
            parameters(3).Direction = ParameterDirection.Output
    
            ReturnResult("updlkpAlbumTypeByKey", parameters, rowsAffected)
    
            Return CInt(parameters(3).Value)
    
    
        End Function
        Public Function UpdateAlbumTypeByDescription(ByVal NewID As String, ByVal NewDescription As String, ByVal description As String) As Integer
    
            Dim rowsAffected As Integer
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).ParameterName = "@AlbumTypeID"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 4
            parameters(0).Value = NewID
            parameters(0).Direction = ParameterDirection.Input
    
            parameters(1).ParameterName = "@Description"
            parameters(1).SqlDbType = SqlDbType.VarChar
            parameters(1).Size = 20
            parameters(1).Value = NewDescription
            parameters(1).Direction = ParameterDirection.Input
    
            parameters(2).ParameterName = "@Original_Description"
            parameters(2).SqlDbType = SqlDbType.VarChar
            parameters(2).Size = 20
            parameters(2).Value = description
            parameters(2).Direction = ParameterDirection.Input
    
            parameters(3).Direction = ParameterDirection.Output
    
            ReturnResult("updlkpAlbumTypeByDescription", parameters, rowsAffected)
    
            Return CInt(parameters(3).Value)
    
    
        End Function
        Public Function GetAlbumTypes() As DataSet
    
            Return ReturnDataset("sellkpAlbumType", New IDataParameter() {}, "Album Types")
    
        End Function
        Public Function GetAlbumTypeByKey(ByVal key As String) As DataSet
    
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).ParameterName = "@Original_AlbumTypeID"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 4
            parameters(0).Value = key
            parameters(0).Direction = ParameterDirection.Input
    
            Return ReturnDataset("sellkpAlbumTypeByDescription", New IDataParameter() {}, "Album Types")
    
        End Function
        Public Function GetAlbumTypeByDescription(ByVal description As String) As DataSet
    
            Dim parameters As SqlParameter() = {New SqlParameter()}
    
            parameters(0).ParameterName = "@Original_Description"
            parameters(0).SqlDbType = SqlDbType.VarChar
            parameters(0).Size = 20
            parameters(0).Value = description
            parameters(0).Direction = ParameterDirection.Input
    
            Return ReturnDataset("sellkpAlbumTypeByKey", New IDataParameter() {}, "Album Types")
    
        End Function
        Public Sub Dispose()
    
            Static Disposed As Boolean = False
    
            If (Disposed) Then
                Exit Sub
            End If
            Disposed = True
    
        End Sub
        Protected Overrides Sub Finalize()
    
            Dispose()
            MyBase.Finalize()
    
        End Sub
    
    End Class
    and here's the module code
    Code:
    Module Module1
        Dim x As New Artist
    
        x,DataProviderName = "System.Data.SqlClient"
    End Module
    The error is Declaration expected.

  7. #7
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Can't Access Properties Of Declared Instance Of A Class

    This looks like a typo:
    Code:
        x,DataProviderName = "System.Data.SqlClient"
    It is presumably meant to be:
    Code:
        x.DataProviderName = "System.Data.SqlClient"

  8. #8

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    Opps my bad. I fixed the typo but still produces the same error.

  9. #9

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    I figured it out. I had to put the code inside a procedure. Once I did that it works fine. I am still wrestling with some of the design issues of both the DAL/BLL. I need a clean way to kick start the process. A class that gets declared when the app starts up that has all the necessary pieces to establish the connection so the DAL/BLL/and UI can do their thing. A DataManager Class. Anyone have any thoughts?

  10. #10

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    Thought you might be interested to know that your blog popped up during one of my internet searches. I did read over the content. It was helpful. Thank you

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Can't Access Properties Of Declared Instance Of A Class

    My thought is that such a class would slightly dilute the benefits you seem to be trying for. It seems like you would like to be able to be flexible as to what database is being used behind the program. Any class will lock you into one version...unless that class is configured to use different things on startup. For example, it might read a file and decide which information is needed to initialize the DAL/BLL based on that. The file would contain the minimum information necessary to use different types of databases. That minimum information might be VERY minimal, so even a file might be overkill.
    My usual boring signature: Nothing

  12. #12

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    Shaggy,

    I've posted a copy of the DAL's code and a class module that uses the is part of my BLL. I haven't been able to find any examples of how to correctly implement a Factory Based DAL. I'm not sure I'm doing it right and my startup process seems ugly. Could you take a look and give me your thoughts please?

    Thanks

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Can't Access Properties Of Declared Instance Of A Class

    I don't like the constructor in the DAL. I think I see where you're going at, but the way you have the constructor written, it doesn't do anything predictable. If the argument is useful, you may end up with a connection object. If the argument is not useful...what do you end up with? Probably no usable class.

    I've occasionally done something kind of similar to that, but on internal classes that will only be created in constrained situations, and always when failure indicates either a bug, or a truly exceptional circumstance (like the DB was there before the class was created, but happened to crash just before the class was created).

    The general rule is that the constructor should always succeed. Once the constructor has finished running, the class should be in some discernable state. In your case, you could check whether the connection was Nothing, but you may not even get that far. After all, your implementation of CreateConnection can throw an exception, which means that the results of creating an instance of the DAL could be

    1) A connection (though it may not be a good one, because it appears to be untested).
    2) Nothing at all.
    3) An exception.

    I don't know what .NET does if a constructor throws an exception. It's considered to be very bad form, because the class ends up being in an unknown state. Since that's untenable in a program, .NET must be handling it in some fashion, I just don't know what fashion that would be.
    My usual boring signature: Nothing

  14. #14

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    Shaggy some of my code is in a state of flux because I haven't figured out the best way to go about it. The idea was to pass a Provider Name. If good then create the Factory create the connection and build the connection string, if step 1 fails error message. Since the Provider Name seems to be driving this whole process my thought process was to have my startup process provide that and go from there. I appreciate your patience. I'm treading on new ground.

  15. #15
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Can't Access Properties Of Declared Instance Of A Class

    You might consider having the constructor be pretty basic, while adding a method like Initialize, which takes whatever arguments seem reasonable, and doing your setup in there. Such a method would be able to return information as to whether or not everything worked, whereas a constructor, being a Sub, can't return anything usefully.
    My usual boring signature: Nothing

  16. #16

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    That's kinda what I was trying to do
    Code:
        Public Sub New(ByVal dataProvidername As String)
    
            MyBase.New()
            If FoundProvider(dataProvidername) Then
                _Connection = CreateDbConnection(dataProvidername)
            Else
            End If
    If FoundProvider returned true that means OK the ProviderName is good so let's create a connection. Then if the Connection object is good then build me a connection string and assign it to the connection object as well as set Property values along the way. Seemed like a solid plan. Just having trouble with the best way to implement it. Also am a bit confused about proper implementation of the DAL within the BLL classes. Should the BLL be importing a specific provider or still importing system.data.common and coding using the db level objects. Seems like importing a specific provider into the BLL classes defeats what I'm trying to do. I have not been able to find any specific coding examples of a BLL that utilizes a Factory Based DAL

  17. #17
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Can't Access Properties Of Declared Instance Of A Class

    I'll be honest... I'm not liking the entire setup... you've got a DAL, that's fine... but then your BLL inherits the DAL... and then it's got the data class as well... so that means every time you create an artist or album object, you have to set the DataProvider on each nd everyone... and then saving to the database is done through the individual objects... yuck.

    Here's what I'd do with it:
    DAL -
    * Create both a parameterized and non-parameterized constructor, and make them both private.
    * Create a shared/static method createDAL (or what ever you want to call it) that returns your DAL... create a paremeterized one, or not, or both, depending on your tastes
    * Inside of that, you can then invoke the paramterized or non-parameterized constructor as needed, wrapped with try/catch so that you can handle things if it goes wrong.
    * I'd move the data provider into a config setting, but that's optional
    * There's no need to expose the connection and/or the transaction objects, they should remain internal to the DAL

    * Create basic, plain ordinary data objects (PODA)... this is your Artist, Album, etc. All it should contain are properties.
    * Create another class that implements IList ... interrnally it uses a List(Of ....) ... IT should have a .Save and a .Load method that then uses the DAL to save its contents to the dastabse (or laod it in the case of a .Load) ... and probably also include other .Get or .Load for individual items as needed too...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  18. #18
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Can't Access Properties Of Declared Instance Of A Class

    Quote Originally Posted by VShaneCurtis View Post
    That's kinda what I was trying to do
    Code:
        Public Sub New(ByVal dataProvidername As String)
    
            MyBase.New()
            If FoundProvider(dataProvidername) Then
                _Connection = CreateDbConnection(dataProvidername)
            Else
            End If
    If FoundProvider returned true that means OK the ProviderName is good so let's create a connection. Then if the Connection object is good then build me a connection string and assign it to the connection object as well as set Property values along the way. Seemed like a solid plan. Just having trouble with the best way to implement it. Also am a bit confused about proper implementation of the DAL within the BLL classes. Should the BLL be importing a specific provider or still importing system.data.common and coding using the db level objects. Seems like importing a specific provider into the BLL classes defeats what I'm trying to do. I have not been able to find any specific coding examples of a BLL that utilizes a Factory Based DAL
    The BLL shouldn't know or care anything about what specific provider the DAL is using... in fact, the BLL should only be barely aware of the DAL in the first place. What the DAL saves to (be it a SQL Server, Oracle, Access, XML file, or a simple text file) is irrelevant to the BLL. I doesn'tcare where the data comes from, only that it creates and object, (say Albums) and that when you call albums.Load() the data "just loads". I can't provide a coherent example of the setup I was mentioning in my other reply... I'll see if I can put one together tomorrow.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  19. #19

    Thread Starter
    Member
    Join Date
    Aug 2021
    Posts
    46

    Re: Can't Access Properties Of Declared Instance Of A Class

    Thanks for all your thoughts on this. They are much appreciated. And also appreciate the clarification of the BLL's implementation of the DAL. Have not done anymore work on that because it just felt like I was defeating the purpose of the Factory based DAL. So I haven't coded any others yet. I kinda get what you're saying in the first reply but some of it not so much. I have a pretty decent understanding of the basic concepts of OO but haven't done some of it so I don't quite get it. An example would be nice. It will help me wrap my mind around the concepts. I've done a lot of digging on the net looking at different pieces of code claiming to be a Provider Independent DAL and they're far from it. All of them are hard coded using select cases for each of the standard providers and importing ALL the data providers. I look at it like NO that's not how this is supposed to work. It's Provider Dependent because you've limited the choices. So I at least understand how it's NOT supposed to be done. The DAL is basically supposed to use polymorphism based on the selected Provider Name. Thanks for your help and patience as I "wade through the mud"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width