PC Review


Reply
Thread Tools Rate Thread

Any way to call a method of a class by name?

 
 
bz
Guest
Posts: n/a
 
      12th Feb 2008
Hi,

I have the following situation:
a class can be loaded dynamically, and an object can be created from
it (the class implements an interface I know).
The class can have one or several methods which are not defined by the
interface. I don't know their name, but I could know their signature
(for example such method receive a parameter of type UserProfile and
returns bool)
Also, my interface have a method that returns the name (as string) of
such method
For example I can have a code like this

string authMethod = myobject.GetAuthenticationMethod();

now I want to be able to call that method, with a code like this

UserProfile upf = new UserProfile(userID);
bool retValue = CallByName(myobject, authMethod, upf);

How can I do this?

Thanks
 
Reply With Quote
 
 
 
 
Anthony Jones
Guest
Posts: n/a
 
      12th Feb 2008
"bz" <(E-Mail Removed)> wrote in message
news:f1a63a7d-beee-4698-aefa-(E-Mail Removed)...
> Hi,
>
> I have the following situation:
> a class can be loaded dynamically, and an object can be created from
> it (the class implements an interface I know).
> The class can have one or several methods which are not defined by the
> interface. I don't know their name, but I could know their signature
> (for example such method receive a parameter of type UserProfile and
> returns bool)
> Also, my interface have a method that returns the name (as string) of
> such method
> For example I can have a code like this
>
> string authMethod = myobject.GetAuthenticationMethod();
>
> now I want to be able to call that method, with a code like this
>
> UserProfile upf = new UserProfile(userID);
> bool retValue = CallByName(myobject, authMethod, upf);
>
> How can I do this?


It would make much more sense for your interface to return a delegate for
the function you wish to call. I'll take you throught step by step.

Open a new VB Console project

In Module1 place this class:-

Class UserProfile
Private myUserID As Integer
Public Sub New(ByVal UserID As Integer)
myUserID = UserID
End Sub
Public ReadOnly Property UserID()
Get
Return myUserID
End Get
End Property
End Class

Its just a simulaton UserProfile class.

Now add this line of code to the module:-

Delegate Function BoolUserProfile(ByVal UPF As UserProfile) As Boolean

This is line of code creates a delegate class (derived from
System.Delegate). A delegate can be thought of as a function placeholder.
It defines the expected signature of a function. An instance of such a
delegate class can then be passed a function which it will invoke when told
to. We'll see how to create an instance in later.

Now add this Interface defintiion:-

Interface FuncProvider
Function FetchFunc(ByVal Selector As String) As System.Delegate
End Interface

This is my idea of what your loadable classes ought to implement. The
FetchFunc takes some criteria (I'd just used a string but what ever you
need) and returns the base System.Delegate.

Now add this class:-

Class Implementor
Implements FuncProvider

Private Function FetchFunc(ByVal Selector As String) As System.Delegate _
Implements FuncProvider.FetchFunc
Return New BoolUserProfile(AddressOf DoBoolUserProfile)
End Function

Public Function DoBoolUserProfile(ByVal UPD As UserProfile) As Boolean
Return UPD.UserID = 1
End Function

End Class

This is an example of class you would include in your loadable assembly. I
guess you use reflection to find class that Impement the interface you're
interested in (in my case thats FuncProvider).

This class has a public method that has the expected signature, the
important bit is the code in the FetchFunc implementation:-

Return New BoolUserProfile(AddressOf DoBoolUserProfile)

This creates a new instance of the BoolUserProfile and uses the AddressOf
operator to create an underlying delegate from DoBoolUserProfile method on
the object. N.B. this is an instance method, when called via the delegate
it will have access to the members of the specific instance where it was
created.

This implementation of BoolUserProfile checks whether its UserID is 1 and
returns true if so.

Now in the Sub Main() add this code:-

Dim provider As FuncProvider = New Implementor

Dim upf As New UserProfile(1) 'Change to 2 results in false

Dim bup As BoolUserProfile = DirectCast(provider.FetchFunc("Some
criteria"), _
BoolUserProfile)
Console.WriteLine(bup(upf))

Console.ReadKey()

So now we create an instance of the Implementor and hold a reference to its
FuncProvider interface. Create a new UserProfile object.

We call the FetchFunc passing whatever criteria we need. It will return a
Delegate but we know that in this case it will be a BoolUserProfile delegate
so we cast it up.

Now we can treat the bup delegate variable as if it were a function that
takes a user profile and returns a bool, which here were just writing to the
console.

Of course you could also make your interface return specific delegate types
and create methods for each type on the interface.

This is approach is certainly a lot better than further reflection malarky
you would need to find methods of a specific signature. Whilst doable is
way uglier.


--
Anthony Jones - MVP ASP/ASP.NET


 
Reply With Quote
 
John Vottero
Guest
Posts: n/a
 
      12th Feb 2008
"bz" <(E-Mail Removed)> wrote in message
news:f1a63a7d-beee-4698-aefa-(E-Mail Removed)...
> Hi,
>
> I have the following situation:
> a class can be loaded dynamically, and an object can be created from
> it (the class implements an interface I know).
> The class can have one or several methods which are not defined by the
> interface. I don't know their name, but I could know their signature
> (for example such method receive a parameter of type UserProfile and
> returns bool)
> Also, my interface have a method that returns the name (as string) of
> such method
> For example I can have a code like this
>
> string authMethod = myobject.GetAuthenticationMethod();
>
> now I want to be able to call that method, with a code like this
>
> UserProfile upf = new UserProfile(userID);
> bool retValue = CallByName(myobject, authMethod, upf);
>
> How can I do this?


MethodInfo mi = upf.GetType().GetMethod(authMethod);
bool retValue = mi.Invoke(upf, myObject);

 
Reply With Quote
 
bz
Guest
Posts: n/a
 
      15th Feb 2008
Antony,

Thanks for your very detailed answer.
I planned to use such approach (I write it in C# actually, but that's
the same concept), but it does not address exactly my situation
The issue is, I need to write a front end for a BE app already
developed, which I have to "hook"to my frontend.
I don't have the BE app, so I cannot set references in it to its
methods, etc. The system must be very decoupled. I only have access to
some interfaces (like IUserProfile, etc)
And what I need is to be able to configure the "links" between the BE
and my FE in a config file (app.config / web.config), using BE
assembly name, BE class name, BE method, etc
Then the FE load the info from that config, and using reflection
instantiate the class from the assembly and then calls the method.

John,

Thank you for your suggestion, I think it is exactly what I'm looking
for

Regards
Bogdan


On 12 Feb, 19:46, "Anthony Jones" <A...@yadayadayada.com> wrote:
> "bz" <bzam...@gmail.com> wrote in message
>
> news:f1a63a7d-beee-4698-aefa-(E-Mail Removed)...
>
>
>
>
>
> > Hi,

>
> > I have the following situation:
> > a class can be loaded dynamically, and an object can be created from
> > it (the class implements an interface I know).
> > The class can have one or several methods which are not defined by the
> > interface. I don't know their name, but I could know their signature
> > (for example such method receive a parameter of type UserProfile and
> > returns bool)
> > Also, my interface have a method that returns the name (as string) of
> > such method
> > For example I can have a code like this

>
> > string authMethod = myobject.GetAuthenticationMethod();

>
> > now I want to be able to call that method, with a code like this

>
> > UserProfile upf = new UserProfile(userID);
> > bool retValue = CallByName(myobject, authMethod, upf);

>
> > How can I do this?

>
> It would make much more sense for your interface to return a delegate for
> the function you wish to call. *I'll take you throught step by step.
>
> Open a new *VB Console project
>
> In Module1 place this class:-
>
> *Class UserProfile
> * Private myUserID As Integer
> * Public Sub New(ByVal UserID As Integer)
> * *myUserID = UserID
> * End Sub
> * Public ReadOnly Property UserID()
> * *Get
> * * Return myUserID
> * *End Get
> * End Property
> *End Class
>
> Its just a simulaton UserProfile class.
>
> Now add this line of code to the module:-
>
> Delegate Function BoolUserProfile(ByVal UPF As UserProfile) As Boolean
>
> This is line of code creates a delegate class (derived from
> System.Delegate). *A delegate can be thought of as a function placeholder.
> It defines the expected signature of a function. *An instance of such a
> delegate class can then be passed a function which it will invoke when told
> to. *We'll see how to create an instance in later.
>
> Now add this Interface defintiion:-
>
> *Interface FuncProvider
> * Function FetchFunc(ByVal Selector As String) As System.Delegate
> *End Interface
>
> This is my idea of what your loadable classes ought to implement. *The
> FetchFunc takes some criteria (I'd just used a string but what ever you
> need) and returns the base System.Delegate.
>
> Now add this class:-
>
> *Class Implementor
> * Implements FuncProvider
>
> * Private Function FetchFunc(ByVal Selector As String) As System.Delegate _
> * Implements FuncProvider.FetchFunc
> * *Return New BoolUserProfile(AddressOf DoBoolUserProfile)
> * End Function
>
> * Public Function DoBoolUserProfile(ByVal UPD As UserProfile) As Boolean
> * *Return UPD.UserID = 1
> * End Function
>
> *End Class
>
> This is an example of class you would include in your loadable assembly. *I
> guess you use reflection to find class that Impement the interface you're
> interested in (in my case thats FuncProvider).
>
> This class has a public method that has the expected signature, the
> important bit is the code in the FetchFunc implementation:-
>
> Return New BoolUserProfile(AddressOf DoBoolUserProfile)
>
> This creates a new instance of the BoolUserProfile and uses the AddressOf
> operator to create an underlying delegate from DoBoolUserProfile method on
> the object. *N.B. this is an instance method, when called via the delegate
> it will have access to the members of the specific instance where it was
> created.
>
> This implementation of BoolUserProfile checks whether its UserID is 1 and
> returns true if so.
>
> Now in the Sub Main() add this code:-
>
> * Dim provider As FuncProvider = New Implementor
>
> * Dim upf As New UserProfile(1) 'Change to 2 results in false
>
> * Dim bup As BoolUserProfile = DirectCast(provider.FetchFunc("Some
> criteria"), _
> * * BoolUserProfile)
> * Console.WriteLine(bup(upf))
>
> * Console.ReadKey()
>
> So now we create an instance of the Implementor and hold a reference to its
> FuncProvider interface. *Create a new UserProfile object.
>
> We call the FetchFunc passing whatever criteria we need. *It will returna
> Delegate but we know that in this case it will be a BoolUserProfile delegate
> so we cast it up.
>
> Now we can treat the bup delegate variable as if it were a function that
> takes a user profile and returns a bool, which here were just writing to the
> console.
>
> Of course you could also make your interface return specific delegate types
> and create methods for each type on the interface.
>
> This is approach is certainly a lot better than further reflection malarky
> you would need to find methods of a specific signature. *Whilst doable is
> way uglier.
>
> --
> Anthony Jones - MVP ASP/ASP.NET- Ascunde citatul -
>
> - Afișare text în citat -


 
Reply With Quote
 
bz
Guest
Posts: n/a
 
      15th Feb 2008
Hi

Thank you for both answers

Best regards,
Bogdan



On 12 Feb, 23:12, "John Vottero" <(E-Mail Removed)> wrote:
> "bz" <(E-Mail Removed)> wrote in message
>
> news:f1a63a7d-beee-4698-aefa-(E-Mail Removed)...
>
>
>
>
>
> > Hi,

>
> > I have the following situation:
> > a class can be loaded dynamically, and an object can be created from
> > it (the class implements an interface I know).
> > The class can have one or several methods which are not defined by the
> > interface. I don't know their name, but I could know their signature
> > (for example such method receive a parameter of type UserProfile and
> > returns bool)
> > Also, my interface have a method that returns the name (as string) of
> > such method
> > For example I can have a code like this

>
> > string authMethod = myobject.GetAuthenticationMethod();

>
> > now I want to be able to call that method, with a code like this

>
> > UserProfile upf = new UserProfile(userID);
> > bool retValue = CallByName(myobject, authMethod, upf);

>
> > How can I do this?

>
> MethodInfo mi = upf.GetType().GetMethod(authMethod);
> bool retValue = mi.Invoke(upf, myObject);- Ascunde citatul -
>
> - Afișare text în citat -


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Derived class Interface method needs to call Base Class Interface Method Kevin Frey Microsoft C# .NET 2 1st Dec 2006 06:57 PM
call a mnuFileNew_Click method from a Main MDI class from another class (can be a MdiChild class.. )? M. G, Microsoft Dot NET Framework Forms 1 31st May 2006 06:28 AM
Is it possible to call a static method in the type class of a generic class? steve bull Microsoft C# .NET 10 8th Dec 2005 09:36 PM
Warning 1684 CA2214 : Microsoft.Usage : 'RandomShade..ctor(Int32, Int32, Int32, Int32, Int32)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: steve bull Microsoft C# .NET 4 7th Jul 2005 05:54 PM
find what class name ,call other class method.. tony Microsoft Dot NET 1 26th Mar 2005 01:53 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 02:26 PM.