c# - Serialising predicates over wcf -
i have wcf service exposes bunch of methods return business objects. under hood has nice repository layer uses interface methods this:
ienumerable<user> getusers(func<user, bool> predicate);
so if want users within given role can do:
var plebs = getusers(u => u.roles.contains(plebrole));
now want expose any-filter-can-be-satisfied thinking on wcf interface. wcf api needs accessible non .net clients want use (relatively) simple types.
i have filter object holds property name , and value:
[datacontract] public class filter { [datamember] public string property { get; set; } [datamember] public string value { get; set; } }
so can expose wcf method this:
ienumerable<user> getusers(ienumerable<filter> filters);
then can build predicates based on comes in, in clients filters. gets messy:
private static expression<func<t, bool>> getpredicate<t>(filter filter) { var knownpredicates = getknownpredicates<t>(filter.value); var t = typeof(t); return knownpredicates.containskey(t) && knownpredicates[t].containskey(filter.property) ? knownpredicates[t][filter.property] : true<t>(); } private static dictionary<type, dictionary<string, expression<func<t, bool>>>> getknownpredicates<t>(string value) { // resharper disable possiblenullreferenceexception return new dictionary<type, dictionary<string, expression<func<t, bool>>>> { { typeof (user), new dictionary<string, expression<func<t, bool>>> { { "forename", x => (x user).forename == value }, { "isadult", x => (x user).isadult.tostring() == value }, ... } }, { typeof (group), new dictionary<string, expression<func<t, bool>>> { { "name", x => (x group).name == value }, ... } }, ... }; // resharper restore possiblenullreferenceexception }
until started writing getknownpredicates method, code didn't stink. does. how fix it?
if want super-fancy use system.linq.expressions.expression class dynamically build predicate based on passed-in filter. know type you're going search, need create property expression using filter.property , constant expression filter.value. use them compose equal expression , you're near finish line.
getting used composing expressions can pain, debugger helpful , show code expression compose it, dive in , try out!
Comments
Post a Comment