I have many similar classes in a project, one for each type of report
my app can create. I want to instantiate them based on a value passed
in by a scheduler module.
Right now I have
Sub RunReports(sReport)
Select Case sReport
Case "CRByDistrict"
oReport = New CRByDistrict
Case "CRCareConversionRate"
oReport = New CRCareConversionRate
Case (etc.....)
End Select
oReport.Build ' All classes implement a Build method
End Sub
For example, if the scheduler says it's time to run the "CRByDistrict"
report I want to pass in "CRByDistrict" and invoke
oReport = New <className> ' One line handles all reports
where in this case <className> is "CRByDistrict". I've looked at
Activator.CreateInstance and some other things, but I can't figure out
the best, simplest way to do this.
I'm tired of maintaining what has become a huge Select Case statement
each time I add a new report (class).
Thanks,
Brian 13 2272
IMHO, Activactor.CreateInstance should be the way to go for you. Since you
have all your classes in the same project (and hence the same assembly), it
should be pretty simple to use this method. Something like:
dim reportType = Type.GetType(sReport)
dim reportObject = Activator.CreateInstance(reportType)
Or
dim reportObject = Activator.CreateInstance(Nothing, sReport)
hope that helps..
Imran.
"Brian" <br******@hotmail.com> wrote in message
news:b6**************************@posting.google.c om... I have many similar classes in a project, one for each type of report my app can create. I want to instantiate them based on a value passed in by a scheduler module.
Right now I have
Sub RunReports(sReport) Select Case sReport Case "CRByDistrict" oReport = New CRByDistrict
Case "CRCareConversionRate" oReport = New CRCareConversionRate
Case (etc.....) End Select
oReport.Build ' All classes implement a Build method End Sub
For example, if the scheduler says it's time to run the "CRByDistrict" report I want to pass in "CRByDistrict" and invoke
oReport = New <className> ' One line handles all reports
where in this case <className> is "CRByDistrict". I've looked at Activator.CreateInstance and some other things, but I can't figure out the best, simplest way to do this.
I'm tired of maintaining what has become a huge Select Case statement each time I add a new report (class).
Thanks, Brian
In article <b6**************************@posting.google.com >, Brian wrote: I have many similar classes in a project, one for each type of report my app can create. I want to instantiate them based on a value passed in by a scheduler module.
Right now I have
Sub RunReports(sReport) Select Case sReport Case "CRByDistrict" oReport = New CRByDistrict
Case "CRCareConversionRate" oReport = New CRCareConversionRate
Case (etc.....) End Select
oReport.Build ' All classes implement a Build method End Sub
For example, if the scheduler says it's time to run the "CRByDistrict" report I want to pass in "CRByDistrict" and invoke
oReport = New <className> ' One line handles all reports
where in this case <className> is "CRByDistrict". I've looked at Activator.CreateInstance and some other things, but I can't figure out the best, simplest way to do this.
I'm tired of maintaining what has become a huge Select Case statement each time I add a new report (class).
Thanks, Brian
I am assuming that all of the report classes implement a specific
interface or inherit from a common base class - but for this example
I'll assume an interface named IReport that has the Build method defined.
Given the above, something like this should work:
Private Sub RunReport (ByVal ReportType As String)
Dim report As IReport = DirectCast _
(Activator.CreateInstance (Type.GetType (ReportType)), _
IReport)
report.Build()
End Sub
--
Tom Shelton [MVP]
oops..that wouldn't even compile ;-)
I meant:
dim reportType As Type = Type.GetType(sReport)
dim reportObject As Object = Activator.CreateInstance(reportType)
Or
dim reportObject as Object = Activator.CreateInstance(Nothing, sReport)
"Imran Koradia" <no****@microsoft.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl... IMHO, Activactor.CreateInstance should be the way to go for you. Since you have all your classes in the same project (and hence the same assembly),
it should be pretty simple to use this method. Something like:
dim reportType = Type.GetType(sReport) dim reportObject = Activator.CreateInstance(reportType)
Or
dim reportObject = Activator.CreateInstance(Nothing, sReport)
hope that helps.. Imran.
"Brian" <br******@hotmail.com> wrote in message news:b6**************************@posting.google.c om... I have many similar classes in a project, one for each type of report my app can create. I want to instantiate them based on a value passed in by a scheduler module.
Right now I have
Sub RunReports(sReport) Select Case sReport Case "CRByDistrict" oReport = New CRByDistrict
Case "CRCareConversionRate" oReport = New CRCareConversionRate
Case (etc.....) End Select
oReport.Build ' All classes implement a Build method End Sub
For example, if the scheduler says it's time to run the "CRByDistrict" report I want to pass in "CRByDistrict" and invoke
oReport = New <className> ' One line handles all reports
where in this case <className> is "CRByDistrict". I've looked at Activator.CreateInstance and some other things, but I can't figure out the best, simplest way to do this.
I'm tired of maintaining what has become a huge Select Case statement each time I add a new report (class).
Thanks, Brian
I guess I'm missing something fundamental here. I tried your (very helpful)
suggestion, but Type.GetType(sReport) returns Nothing in my case.
Should I be doing something in my class definitions to set their Type? I
don't have a base class.
Thanks,
Brian
"Imran Koradia" <no****@microsoft.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl... oops..that wouldn't even compile ;-)
I meant:
dim reportType As Type = Type.GetType(sReport) dim reportObject As Object = Activator.CreateInstance(reportType)
Or
dim reportObject as Object = Activator.CreateInstance(Nothing, sReport)
"Imran Koradia" <no****@microsoft.com> wrote in message news:%2****************@TK2MSFTNGP10.phx.gbl... IMHO, Activactor.CreateInstance should be the way to go for you. Since
you have all your classes in the same project (and hence the same assembly), it should be pretty simple to use this method. Something like:
dim reportType = Type.GetType(sReport) dim reportObject = Activator.CreateInstance(reportType)
Or
dim reportObject = Activator.CreateInstance(Nothing, sReport)
hope that helps.. Imran.
"Brian" <br******@hotmail.com> wrote in message news:b6**************************@posting.google.c om... I have many similar classes in a project, one for each type of report my app can create. I want to instantiate them based on a value passed in by a scheduler module.
Right now I have
Sub RunReports(sReport) Select Case sReport Case "CRByDistrict" oReport = New CRByDistrict
Case "CRCareConversionRate" oReport = New CRCareConversionRate
Case (etc.....) End Select
oReport.Build ' All classes implement a Build method End Sub
For example, if the scheduler says it's time to run the "CRByDistrict" report I want to pass in "CRByDistrict" and invoke
oReport = New <className> ' One line handles all reports
where in this case <className> is "CRByDistrict". I've looked at Activator.CreateInstance and some other things, but I can't figure out the best, simplest way to do this.
I'm tired of maintaining what has become a huge Select Case statement each time I add a new report (class).
Thanks, Brian
Sorry - I should have been more complete. If your class is under a
namespace, you'll need to provide the namespace information to the GetType
method as well. By default, VB .NET uses the application name as the default
namespace which is why you would need to do this. You can check the default
namespace from Project --> <your project> Properties -- > Root Namespace
field. You can change that to whatever you like or you can even wipe it out
altogether. In general, you'll need to provide the entire namespace
hierarchy. For example:
If your project name is "myProject", by default, your root namespace will be
"myProject". (For project names with spaces, I believe VB .NET uses and
underscore instead of the spaces; so "My Project" becomes "My_Project").
Suppose your report class is something like:
NameSpace AllReports
....
....
Class CRByDistrict
Public Sub Build( )
End Sub
End Class
Class CRCareConversionRate
Public Sub Build( )
End Sub
End Class
....
....
End NameSpace
Then you would do:
Sub RunReports(sReport)
Dim reportType As Type = _
Type.GetType("myProject." & "AllReports." & sReport)
Dim reportObject As Object = _
Activator.CreateInstance(myType)
reportType.InvokeMember("Build", _
Reflection.BindingFlags.InvokeMethod, _
Nothing, reportObject, Nothing)
End Sub
Ofcourse, if you have no namespaces and if you are going to wipe out the
default namespace as well, then you can directly use the report class name
in the Type.GetType method. Thats upto how you would want it.
hope that helps..
Imran.
"Brian Fenske" <br******@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl... I guess I'm missing something fundamental here. I tried your (very helpful) suggestion, but Type.GetType(sReport) returns Nothing in my case.
Should I be doing something in my class definitions to set their Type? I don't have a base class.
Thanks, Brian
"Imran Koradia" <no****@microsoft.com> wrote in message news:%2***************@TK2MSFTNGP15.phx.gbl... oops..that wouldn't even compile ;-)
I meant:
dim reportType As Type = Type.GetType(sReport) dim reportObject As Object = Activator.CreateInstance(reportType)
Or
dim reportObject as Object = Activator.CreateInstance(Nothing, sReport)
"Imran Koradia" <no****@microsoft.com> wrote in message news:%2****************@TK2MSFTNGP10.phx.gbl... > IMHO, Activactor.CreateInstance should be the way to go for you. Since you > have all your classes in the same project (and hence the same > assembly), it > should be pretty simple to use this method. Something like: > > dim reportType = Type.GetType(sReport) > dim reportObject = Activator.CreateInstance(reportType) > > Or > > dim reportObject = Activator.CreateInstance(Nothing, sReport) > > hope that helps.. > Imran. > > "Brian" <br******@hotmail.com> wrote in message > news:b6**************************@posting.google.c om... > > I have many similar classes in a project, one for each type of report > > my app can create. I want to instantiate them based on a value > > passed > > in by a scheduler module. > > > > Right now I have > > > > Sub RunReports(sReport) > > Select Case sReport > > Case "CRByDistrict" > > oReport = New CRByDistrict > > > > Case "CRCareConversionRate" > > oReport = New CRCareConversionRate > > > > Case (etc.....) > > End Select > > > > oReport.Build ' All classes implement a Build method > > End Sub > > > > For example, if the scheduler says it's time to run the > > "CRByDistrict" > > report I want to pass in "CRByDistrict" and invoke > > > > oReport = New <className> ' One line handles all reports > > > > where in this case <className> is "CRByDistrict". I've looked at > > Activator.CreateInstance and some other things, but I can't figure > > out > > the best, simplest way to do this. > > > > I'm tired of maintaining what has become a huge Select Case statement > > each time I add a new report (class). > > > > Thanks, > > Brian > >
On 2004-09-14, Imran Koradia <no****@microsoft.com> wrote: Sorry - I should have been more complete. If your class is under a namespace, you'll need to provide the namespace information to the GetType method as well.
It's worth adding that Type.GetType is more than a bit flaky. It works
well with the standard assemblies, usually works inside a single
assembly application, but once you get into multiple assemblies all bets
are off.
In all honesty, I've never figured out the pattern to when it works or
not. Sometimes it works even across assemblies, and sometimes it
doesn't (even using the AssemblyQualifiedName doesn't help in this
situation). I'd be very interested if somebody has spent the time to
track this down, since it's a very useful function.
Personally, I'd be very wary of using it in the situation in this
thread, since with this type of system the logical next step is a plugin
system where you load new report types without recompiling, and
Type.GetType is highly unlikely to work reliably in that situation.
You're probably better off looping through known assemblies looking for
a specific interface (do it once at startup then stash away the types
you find). It's a bit more code right now, but you gain a lot in
robustness and expandability.
Hmm. I haven't had problems with the GetType method as such but honestly,
I've not used it so extensively either to be a good judge of its
reliability. Brian - if you think thats going to be a problem, here's
another way to accomplish the same thing:
Imports System.Reflection
Dim reportObject As Object = _
[Assembly].GetExecutingAssembly.CreateInstance("myProject" & sReport)
CallByName(reportObject, "Build", CallType.Method, Nothing)
Imran.
"David" <df*****@woofix.local.dom> wrote in message
news:slrnckck1a.qmv.df*****@woofix.local.dom... On 2004-09-14, Imran Koradia <no****@microsoft.com> wrote: Sorry - I should have been more complete. If your class is under a namespace, you'll need to provide the namespace information to the GetType method as well.
It's worth adding that Type.GetType is more than a bit flaky. It works well with the standard assemblies, usually works inside a single assembly application, but once you get into multiple assemblies all bets are off.
In all honesty, I've never figured out the pattern to when it works or not. Sometimes it works even across assemblies, and sometimes it doesn't (even using the AssemblyQualifiedName doesn't help in this situation). I'd be very interested if somebody has spent the time to track this down, since it's a very useful function.
Personally, I'd be very wary of using it in the situation in this thread, since with this type of system the logical next step is a plugin system where you load new report types without recompiling, and Type.GetType is highly unlikely to work reliably in that situation. You're probably better off looping through known assemblies looking for a specific interface (do it once at startup then stash away the types you find). It's a bit more code right now, but you gain a lot in robustness and expandability.
* br******@hotmail.com (Brian) scripsit: I have many similar classes in a project, one for each type of report my app can create. I want to instantiate them based on a value passed in by a scheduler module.
\\\
Dim frm As Form = _
DirectCast( _
Activator.CreateInstance( _
Type.GetType("MyApplication.SampleForm") _
), _
Form _
)
frm.Show()
///
More general:
\\\
Private Function CreateClassByName( _
ByVal PartialAssemblyName As String, _
ByVal QualifiedClassName As String _
) As Object
Return _
Activator.CreateInstance( _
[Assembly].LoadWithPartialName( _
PartialAssemblyName _
).GetType(QualifiedClassName) _
)
End Function
///
Usage:
\\\
Dim c As Control = _
DirectCast( _
CreateClassByName( _
"System.Windows.Forms", _
"System.Windows.Forms.Button" _
), _
Control _
)
With c
.Location = New Point(10, 10)
.Size = New Size(80, 26)
.Text = "Hello World"
End With
Me.Controls.Add(c)
///
--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
In article <sl********************@woofix.local.dom>, David wrote: On 2004-09-14, Imran Koradia <no****@microsoft.com> wrote: Sorry - I should have been more complete. If your class is under a namespace, you'll need to provide the namespace information to the GetType method as well.
It's worth adding that Type.GetType is more than a bit flaky. It works well with the standard assemblies, usually works inside a single assembly application, but once you get into multiple assemblies all bets are off.
Never had a lick of trouble with it myself....
--
Tom Shelton [MVP]
Well, after trying many different ways to get back a Type, I gave up on
GetType.
I used Object Browser to note that my Namespace is indeed the name of my
project as well as the executable (which must be the defaults for a VB
project since I didn't attempt to change any of them when I ran the project
wizard): CRMReportGenerator
So I tried the following, all of which return Nothing:
Type.GetType(sReport)
Type.GetType("CRMReportGenerator." & sReport)
Type.GetType("CRMReportGenerator.CRMReportGenerato r." & sReport)
Type.GetType("DSR Report Generator.CRMReportGenerator." & sReport) ' Here I
tried the Assembly name found in Assembly.vb
Maybe there is a combo I didn't try that works.
Anyway, here is what did work:
Imports System.Reflection
Dim oReport as Object
oReport =
[Assembly].GetExecutingAssembly.CreateInstance("CRMReportGen erator." &
sReport)
oReport.Build
Short and sweet.
Thank you all for your help!
Brian
"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:e6**************@tk2msftngp13.phx.gbl... * br******@hotmail.com (Brian) scripsit: I have many similar classes in a project, one for each type of report my app can create. I want to instantiate them based on a value passed in by a scheduler module.
\\\ Dim frm As Form = _ DirectCast( _ Activator.CreateInstance( _ Type.GetType("MyApplication.SampleForm") _ ), _ Form _ ) frm.Show() ///
More general:
\\\ Private Function CreateClassByName( _ ByVal PartialAssemblyName As String, _ ByVal QualifiedClassName As String _ ) As Object Return _ Activator.CreateInstance( _ [Assembly].LoadWithPartialName( _ PartialAssemblyName _ ).GetType(QualifiedClassName) _ ) End Function ///
Usage:
\\\ Dim c As Control = _ DirectCast( _ CreateClassByName( _ "System.Windows.Forms", _ "System.Windows.Forms.Button" _ ), _ Control _ ) With c .Location = New Point(10, 10) .Size = New Size(80, 26) .Text = "Hello World" End With Me.Controls.Add(c) ///
-- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
Oops, I was not entirely correct. My Assembly Title is "DSR Report
Generator". My AssemblyName and Root Namespace are "CRMReportGenerator"
Brian
"Tom Shelton" <to*@YOUKNOWTHEDRILLmtogden.com> wrote in message
news:u%****************@tk2msftngp13.phx.gbl... In article <sl********************@woofix.local.dom>, David wrote: On 2004-09-14, Imran Koradia <no****@microsoft.com> wrote: Sorry - I should have been more complete. If your class is under a namespace, you'll need to provide the namespace information to the
GetType method as well.
It's worth adding that Type.GetType is more than a bit flaky. It works well with the standard assemblies, usually works inside a single assembly application, but once you get into multiple assemblies all bets are off.
Never had a lick of trouble with it myself....
-- Tom Shelton [MVP]
> Anyway, here is what did work: Imports System.Reflection
Dim oReport as Object oReport = [Assembly].GetExecutingAssembly.CreateInstance("CRMReportGen erator." & sReport)
That's what I suggested in my 3rd post...
oReport.Build
This will only work if you have Option Strict Off. If you have Option Strict
On, you would need to typecast to the actual report type. Since dynamic
casting cannot be accomplished, you'll need to use CallByName to execute the
method as I mentioned in that post.
Imran.
In article <uf**************@TK2MSFTNGP15.phx.gbl>, Imran Koradia wrote: Anyway, here is what did work:
Imports System.Reflection
Dim oReport as Object oReport = [Assembly].GetExecutingAssembly.CreateInstance("CRMReportGen erator." & sReport)
That's what I suggested in my 3rd post...
oReport.Build
This will only work if you have Option Strict Off. If you have Option Strict On, you would need to typecast to the actual report type. Since dynamic casting cannot be accomplished, you'll need to use CallByName to execute the method as I mentioned in that post.
Imran.
Or just make them all implement a specific interface... That way, you
can have early binding....
Dim report As IReport
report = CType (....., IReport)
report.Build()
In fact, that is the way I would probably do this.
--
Tom Shelton [MVP] This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Swartz |
last post by:
Hi all.
I'm working here on a small project of mine. I'm not new to programming, but
I'm new to PHP. You have to understand that I'm coming from C++, OOP world,
so my code might seems a little...
|
by: David |
last post by:
Hello.
I am looking for advice on what is "best practice" regarding looping
through a form to check its checkboxes and associated data fields.
Here is what I am trying to do (Here is the page...
|
by: Chuck Ritzke |
last post by:
I keep asking myself this question as I write class modules. What's the
best/smartest/most efficient way to send a large object back and forth to a
class module?
For example, say I have a data...
|
by: Anonieko Ramos |
last post by:
ASP.NET Forms Authentication Best Practices
Dr. Dobb's Journal February 2004
Protecting user information is critical
By Douglas Reilly
Douglas is the author of Designing Microsoft ASP.NET...
|
by: h7qvnk7q001 |
last post by:
I'm trying to implement a simple server-side form validation (No
Javascript). If the user submits a form with errors, I want to
redisplay the same form with the errors highlighted. Once the form...
|
by: Steve |
last post by:
I am building an object library for tables in a database. What is the
best practice for creating objects like this?
For example, say I have the following tables in my database:
User:
- Id
-...
|
by: raylopez99 |
last post by:
Hi,
Best practices question.
When receiving an object passed from another method, is it a good idea
to use a shallow copy with a temporary object received on the RHS
(right hand side of =),...
|
by: bsturg21 |
last post by:
Hello,
I have a windows form that has a series of linklabels on it, and I
need to have each linklabel, when clicked, open a separate windows
form that has a single paramter passed into it. The...
|
by: tshad |
last post by:
Using VS 2003, I am trying to take a class that I created to create new
variable types to handle nulls and track changes to standard variable types.
This is for use with database variables. This...
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: PapaRatzi |
last post by:
Hello,
I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
| |