Get method name using Lambda expression

I am trying to get the method name for a type using a lambda expression. I am using Windows Identity Foundation and must define access policies with a type name with a namespace as a resource and a method name as an action. Here is an example.

This is the type from which I get the type name and method name:

namespace My.OrderEntry { public class Order { public void AddItem(string itemNumber, int quantity) {} } } 

Here is how I would like to define an access policy through DSL:

 ForResource<Order>().Performing(o => o.AddItem).AllowUsersHaving(new Claim()); 

From this statement, I would like to get "My.OrderEntry.Order" as a resource and "AddItem" as an action. Getting a type name with a namespace is not a problem, but I don't think I can use lambda for the method I'm trying to do.

 public static IPermissionExp Performing<T>( this IActionExp<T> exp, Func<T, delegate???> action) {} //this is where I don't know what to define 

Can this be done? Is there any other way to do such things without using magic strings?

+17
reflection c # lambda
Feb 22 2018-10-22
source share
4 answers

There are two ways to do this:

1: you can do overloads that accept various Func and Action delegates (e.g. Expression<Func<T, Func<TParam1,TParam2, TReturn>> ). Please note that your callers must explicitly specify common parameters either in a method call or by creating a delegate. This will be used as follows:

 ForResource<Order>().Performing(o => new Action<string>(o.AddItem)).AllowUsersHaving(new Claim()); 



2: You can take an Expression<Action> , which contains a method call, and parse a MethodInfo that is called from the expression tree. This will be used as follows:

 ForResource<Order>().Performing(o => { o.AddItem(null); }).AllowUsersHaving(new Claim()); 
+7
Feb 22 2018-10-22
source share

This seems to be what you are looking for if you want the name of the action delegation method to be passed to the Run function.

 public static IPermissionExp Performing<T>( this IActionExp<T> exp, Expression<Action<T, string, int>> action) { var expression = action.Body as MethodCallExpression; string actionMethodName = string.Empty; if (expression != null) { actionMethodName = expression.Method.Name; } // use actionMethodName ("AddItem" in the case below) here } 

This will allow you to call a method like this ...

 ForResource<Order>().Performing((o, a, b) => o.AddItem(a, b)).AllowUsersHaving(new Claim()); 
+3
Feb 22 2018-10-22T00
source share

I recently did something at work where you defined a method using lambda, which then got an internal object. You can also use strings or pass to MethodInfo, but the first one is not type safe (and typos are a big risk), and the latter is not very elegant.

Basically, I had such a method (this is not an exact method, it is a bit more advanced):

 public void SetRequest(Request req, Expression<Func<Service, Func<long, IEnumerable<Stuff>>> methodSelector); 

The key here is the “Expression” thing, this allows you to “choose” a method similar to this:

 SetRequest(req, service => service.SomeMethodTakingLongReturningStuffs); 

The method selector turns into an expression tree from which you can extract different bits of data. I don’t remember exactly what the resulting tree looks like, it also depends on how your lambdas look.

+1
Feb 22 '10 at 21:41
source share

Instead, you can pass it as an action that does not call any return type. This is still a bit dirty, because you need to pass some arguments to the method to compile it.

0
Feb 22 '10 at 21:30
source share



All Articles