How to Pass a Lambda Expression to a Wcf Service

How can I pass a lambda expression to a WCF service?

Perhaps a dynamic query would work in your situation?

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

You would pass a where clause string to the service which would validate and convert it to an expression

I want to be able to use a lambda expression to specify a range of values to return over a wcf service

You could declare the GetGroups method with a parameter of type Expression<Func<Group, bool>>, which represents a predicate that the group must match in order to be returned :

IList<Group> GetGroups(Expression<Func<Group, bool>> predicateExpression);

The trouble is, expressions can't be serialized, so you couldn't send it to the WCF service... However, you might find a way to do it with the Expression Tree Serialization project.

Can you Pass FuncT,bool Through a WCF Service?

There's work happening to enable it. Check out the Expression Tree Serialization project on the MSDN Code Gallery.

Should the UI layer be able to pass lambda expressions into the service layer instead of calling a specific method?

This is a judgement call based on the situation. It's not necessarily wrong to pass in a predicate like this. I think it should be considered a minor bad smell though.

If the passing in of a lambda expression allows you to reduce 6 methods down to 1, then it might be a good move. On the other hand, if you can just as easily pass in a simple type, then lambda syntax is a needless complication.

In the above example, not knowing the context, my preference would be to use a simple integer parameter. There should usually be a basic method that just gets a record by it's ID. And maybe one or two other such methods that are repeatedly used through your application. And then maybe a general purpose method that takes a lambda.

You should also consider what some would suggest should be a rule: that you not have any methods with lambda-specified predicates between your UI and your business layer. (And some believe, with reason, that your repositories shouldn't even have such methods!) I don't believe this should be an iron-clad rule, but there's good reasons for it. Your business and data layers, between them, should keep dangerous queries from happening. If you allow the passing in of lambdas, it's very easy for a junior developer in the UI layer to specify queries that could really hose your database. (For example, they'll do huge queries against non-indexed fields, and/or filter against the resultset using LINQ-to-objects, and not realize how inefficient that is.)

Like many other good practices, this will depend somewhat on scope. In my recent large application, I have no passing of lambda syntax from the UI layer to the business layer. My plan was to invest heavily in the business layer, to make it very smart. It has all the needed methods with simple types. In fact, it typically gives you what you need through simple domain object properties, with no parameters at all. My interface assures that the UI can only cause efficient queries to happen, with perhaps just minor LINQ-to-Objects predicates in the UI layer. (This goes even for "search" pages. My business layer accepts a criteria object with constrained possibilities, and ensures an efficient query.)

Now, you said "layers", rather than "tiers". So these are all in the same assembly? Another disadvantage of lambda is they're (currently) difficult to serialize. So you'd regret them if you had to separate your tiers.

Lambda-expression for querying web service/method?

No, you can't pass lambdas or delegates in WCF method.
For more details see this topic

When I came across your task I used one of this approaches

  1. Creating a separate class for filter parameters and pass an instance to a server. On the server side you need to form a query based on passed object.
  2. Usage of a Dictionary<string,string> as a container for filter parameters. In this case, on the server side you need to parse values if you have enums, guids, etc. Also it has limitations if we have multiple values for filter parameter. But no need to create a separate class.

LINQ: Passing lambda expression as parameter to be executed and returned by method

Something like this:

public IEnumerable<T> ExecuteInContext<T>(
Expression<Func<T,bool>> predicate)
{
... // do your stuff
//eg
Table<T> t = GetTable<T>();
return t.Where(predicate);
}

or

public IEnumerable<T> ExecuteInContext<T>(
IQueryable<T> src, Expression<Func<T,bool>> predicate)
{
return src.Where(predicate);
}

Usage:

var r = repo.ExecuteInContext<SomeType>( 
x => x.SomeProp.Equals(Somevalue));

or

var r = repo.ExecuteInContext(GetTable<T>(), 
x => x.SomeProp.Equals(Somevalue));

Assumptions:

  1. Table can be derived from T, else you will need to pass the source too.
  2. You know how to modify the predicate expression if needed.

Lambda Action Syntax in WCF call

Unless I'm misunderstanding the issue, you should be able to just do this:

    _dataService.Authenticate((authenticated, error) =>
{
if (error != null)
{
}
}, userName, password);


Related Topics



Leave a reply



Submit