-
Aug 31st, 2021, 03:28 AM
#1
Thread Starter
Member
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.
-
Aug 31st, 2021, 04:16 AM
#2
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.
-
Aug 31st, 2021, 09:38 AM
#3
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
-
Aug 31st, 2021, 10:06 AM
#4
Re: Can't Access Properties Of Declared Instance Of A Class
Originally Posted by Shaggy Hiker
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.
-
Aug 31st, 2021, 10:46 AM
#5
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
-
Aug 31st, 2021, 02:31 PM
#6
Thread Starter
Member
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.
-
Aug 31st, 2021, 03:21 PM
#7
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"
-
Aug 31st, 2021, 04:38 PM
#8
Thread Starter
Member
Re: Can't Access Properties Of Declared Instance Of A Class
Opps my bad. I fixed the typo but still produces the same error.
-
Aug 31st, 2021, 07:40 PM
#9
Thread Starter
Member
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?
-
Aug 31st, 2021, 07:43 PM
#10
Thread Starter
Member
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
-
Sep 1st, 2021, 09:09 AM
#11
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
-
Sep 1st, 2021, 01:45 PM
#12
Thread Starter
Member
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
-
Sep 1st, 2021, 02:53 PM
#13
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
-
Sep 1st, 2021, 03:16 PM
#14
Thread Starter
Member
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.
-
Sep 1st, 2021, 08:05 PM
#15
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
-
Sep 1st, 2021, 10:19 PM
#16
Thread Starter
Member
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
-
Sep 1st, 2021, 10:31 PM
#17
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
-
Sep 1st, 2021, 10:37 PM
#18
Re: Can't Access Properties Of Declared Instance Of A Class
Originally Posted by VShaneCurtis
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
-
Sep 2nd, 2021, 12:02 AM
#19
Thread Starter
Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|