Calling a method within a module by variable

hyphen81

Member
Joined
Jul 30, 2014
Messages
5
Programming Experience
1-3
I've looked into this a bit, and it seems that reflection might be the necessary tactic to accomplish what I'm trying to do, but it's confusing as all get out to me for some reason. Looking for a little help with my specific situation.

I'm building a reporting dashboard. I have a combobox populated with a list of clients. When a user selects a client, it needs to populate a second combobox with the reports unique to that client. As an added requirement, in order to add clients easily in the future, they want separate modules with the code for each client. That way they can copy and paste from one module into a new one and customize it for that client without having to make massive changes to the rest of the application.

So...there are modules like client1.vb, client2.vb, and within those modules will be identically named functions or I guess subroutines. For instance, each client would have a function called loadReports() (not totally sure if I can even have multiple methods in different modules named the same thing??) that would get the necessary reports for that specific client and populate the second combobox with the reports.

What I want to do is this: user selects client from combobox, application takes combobox1.selecteditem and stores it to a variable. We'll call the variable "selectedClient". I then want to be able to in essence use the string value of that variable to call the necessary module and method. So it would be selectedClient.loadReports(), where selectedClient = "client1" or whatever.

I'm not sure if that makes sense or not, but I'm just wondering if there's an easier way to do this than with reflection, and either way, how would I accomplish it?
 
I've been doing some reading on interfaces, but I still don't get how I would implement it in my situation. Any help you can provide would be greatly appreciated.

You're not seeing it because the use of interfaces means that you don't have to use Strings to store names of types or members. You said:
So...there are modules like client1.vb, client2.vb, and within those modules will be identically named functions or I guess subroutines.
That's the problem that you're trying to solve that doesn't exist if you use an interface. In this case:
Public Class FirstClass

    Public Sub SomeMethod()
        '...
    End Sub

End Class


Public Class SecondClass

    Public Sub SomeMethod()
        '...
    End Sub

End Class
even though both classes have a method with the same name, they are different methods. There's no way that you can have a single variable that can hold an instance of either class and just call SomeMethod on it. You could do it with late-binding but that's a filthy hack. If you use an interface though, that issue goes away:
Public Interface ISomeInterface

    Sub SomeMethod()

End Interface


Public Class FirstClass
    Implements ISomeInterface
    
    Public Sub SomeMethod() Implements ISomeInterface.SomeMethod
        '...
    End Sub

End Class


Public Class SecondClass
    Implements ISomeInterface
    
    Public Sub SomeMethod() Implements ISomeInterface.SomeMethod
        '...
    End Sub

End Class
Now, both classes have the same method, although different implementations of that same method. Now, you can declare a variable as type ISomeInterface and it can hold an instance of either class. Because SomeMethod is a member of ISomeInterface, you can call SomeMethod directly on that variable without having to care which concrete type the object is:
Dim var As ISomeInterface

var = New FirstClass()

var.SomeMethod()

var = New SecondClass()

var.SomeMethod()
You can simply cast the SelectedItem from the ComboBox as your interface type and assign it to a variable of that type, then call any method that is a member of that interface directly. Each class can implement those methods any way it likes. No Strings, no Reflection.
 
Would using an interface type setup allow me to put all the code specific to a client in separate modules? I want them separated out so in the future in the event that a new client was added, we can just copy a module and replace the information relating to that specific client without effecting others. Obviously probably some code will need to be modified in the main form, but I want to keep that to a minimum.
 
Would using an interface type setup allow me to put all the code specific to a client in separate modules? I want them separated out so in the future in the event that a new client was added, we can just copy a module and replace the information relating to that specific client without effecting others. Obviously probably some code will need to be modified in the main form, but I want to keep that to a minimum.

The whole point of an interface is that, as the name suggests, it defines what you see on the outside of a type but not what it does on the inside. An interface defines what members a type that implements that interface must have and what the general purpose of those members is, but the implementation is left completely up to each implementing type. Each type implements each member in whatever way is appropriate for that type with no thought for how it may be done in any other type. Perhaps some types will implement the same member in the same way but that is just coincidence. In short, the answer to your question is "yes".

If you were to use a common base class instead of a common interface then you could do basically the same thing or you could do it differently. An interface cannot contain any implementation at all but a base class obviously can. If the base class was abstract and every member in it was also abstract then it would be very much like using an interface. You also have the option, though, of providing a default implementation that may or may not be overridden in derived classes.
 
I attempted to implement what you recommended above regarding interfaces, but using separate modules, and I got errors.

Then you did it wrong. Are you expecting us to use ESP to work out how to fix it? Show us what you did, tell us what you expected and how the reality differs from that expectation. If there are errors then there are error messages. Show us code, give us the error messages and tell us where they occur.
 
What was meant here is that in your project template, you include the interface and just a skeleton of the class that implements it. You still need a separate project for each client, if your goal was to include the code for all your clients in the same project then that is the wrong way to do it. Instead you branch from the template using your source control, implement the specific class for the interface, and build. So now you have a separate project for each client, each containing the same interface but a different class implementing it.

Think of an interface as common connector. You can develop the rest of your application around it without ever knowing how it is implemented.
 
What was meant here is that in your project template, you include the interface and just a skeleton of the class that implements it. You still need a separate project for each client, if your goal was to include the code for all your clients in the same project then that is the wrong way to do it. Instead you branch from the template using your source control, implement the specific class for the interface, and build. So now you have a separate project for each client, each containing the same interface but a different class implementing it.

Think of an interface as common connector. You can develop the rest of your application around it without ever knowing how it is implemented.

Ahh..Ok, I was attempting to do it all within the same project. I'm fairly new to vb, but I'll toy around with it based upon your comments and see what I can get figured out.
 
You could always use compiler conditionals (#If) to decide at compile time which client you are building for, and instanciate your class accordingly too, if you want to keep it all in the same project.
 
Back
Top