У меня есть служба WCF, которая предоставляет кучу методов, возвращающих бизнес-объекты. Под его капотом у него есть хороший репозитария слой, который использует методы интерфейса, как это:Сериализация предикатов по wcf
IEnumerable<User> GetUsers(Func<User, bool> predicate);
Так что, если я хочу, чтобы все пользователи в пределах данной роли я могу сделать:
var plebs = GetUsers(u => u.Roles.Contains(plebRole));
Теперь я хочу, чтобы выставить этот any-filter-can-be-satisfied-мышление над интерфейсом WCF. WCF api должен быть доступен для клиентов non .Net, поэтому я хочу использовать (относительно) простые типы.
У меня есть объект фильтра, который содержит имя свойства и и значение:
[DataContract] public class Filter {
[DataMember] public string Property { get; set; }
[DataMember] public string Value { get; set; }
}
Так что теперь я могу выставить метод WCF так:
IEnumerable<User> GetUsers(IEnumerable<Filter> filters);
Тогда я могу построить предикаты на основе что входит в фильтры клиентов. Теперь это становится грязным:
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 as User).Forename == value },
{ "IsAdult", x => (x as User).IsAdult.ToString() == value },
...
}
},
{
typeof (Group), new Dictionary<string, Expression<Func<T, bool>>>
{
{ "Name", x => (x as Group).Name == value },
...
}
},
...
};
// ReSharper restore PossibleNullReferenceException
}
Пока я не начал писать метод GetKnownPredicates, код действительно не воняет. Теперь это так. Как это исправить?
Конечно, вам нужно будет рассмотреть безопасность, поскольку вы не можете позволить конечным пользователям запрашивать какое-либо свойство ваших классов. Возможно, свойства атрибута с настраиваемым атрибутом «ОК для фильтрации», который вы проверяете перед созданием фильтра. – 2010-12-02 14:14:34
Прохладный, это маршрут, который я хочу исследовать. Я не забочусь о безопасности, потому что у меня есть токен аутентификации в объекте запроса, и у меня есть механизм для решения, обрабатывать ли запрос. – grenade 2010-12-02 14:20:47