ビジネスオブジェクトを返すメソッドを公開するWCFサービスがあります。そのフードの下では、このようなインターフェイスのメソッドを使用しています素敵なリポジトリ層を持っていますwcfで述語をシリアライズ
IEnumerable<User> GetUsers(Func<User, bool> predicate);
私が欲しいのであれば、私が行うことができます与えられた役割内のすべてのユーザー:
var plebs = GetUsers(u => u.Roles.Contains(plebRole));
は今、私はこれを公開しますWCFインターフェイス上での任意のフィルタリングが可能な思考。私は(比較的)シンプルな型を使いたいので、WCF APIは.Net以外のクライアントからアクセスできる必要があります。
私はプロパティ名を保持しているFilterオブジェクトを持っており、その値:
[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方法を書き始めまでは、コードは本当に臭いませんでした。今それはあります。どうすれば修正できますか?
もちろん、エンドユーザーがクラスのプロパティを照会できるようにしたくないため、セキュリティを考慮する必要があります。フィルタを作成する前にチェックするカスタムの「OK to Filter」属性を持つ属性を属性に設定することがあります。 –
クール、これは私が探索したいルートです。私は、要求オブジェクトに認証トークンを持っているので、セキュリティを心配していません。要求を処理するかどうかを決定するメカニズムがあります。 – grenade