Guest User

Untitled

a guest
Jun 19th, 2010
360
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     public static class DynamicExtensions
  2.     {
  3.         #region Fields
  4.  
  5.         private static readonly Regex methodMatcher = new Regex(@"^Find(All)?By(\w*)$", RegexOptions.Singleline | RegexOptions.Compiled);
  6.  
  7.         #endregion
  8.  
  9.         #region Public Methods
  10.  
  11.         public static dynamic AsDynamic<T>(this IEnumerable<T> source)
  12.         {
  13.             return new DynamicEnumerable<T>(source);
  14.         }
  15.  
  16.         public static dynamic AsDynamic<T>(this IQueryable<T> source)
  17.         {
  18.             return new DynamicQueryable<T>(source);
  19.         }
  20.  
  21.         #endregion
  22.  
  23.         #region Private Methods
  24.  
  25.         private static Expression<Func<T, bool>> BuildExpression<T>(string[] properties, object[] args)
  26.         {
  27.             if (properties.Length < 1)
  28.                 throw new InvalidOperationException("Need to specify at least one property.");
  29.             if (args.Length != properties.Length)
  30.                 throw new InvalidOperationException("Method expects " + properties.Length + " parameters and only got " + args.Length + " values.");
  31.  
  32.             var param = Expression.Parameter(typeof(T), "p");
  33.             var body = Expression.Equal(Expression.Property(param, properties[0]), Expression.Constant(args[0]));
  34.             for (var i = 1; i < properties.Length; i++)
  35.                 body = Expression.AndAlso(body, Expression.Equal(Expression.Property(param, properties[i]), Expression.Constant(args[i])));
  36.             return Expression.Lambda<Func<T, bool>>(body, param);
  37.         }
  38.  
  39.         #endregion
  40.  
  41.         #region Nested Types
  42.  
  43.         private sealed class DynamicEnumerable<T> : DynamicObject
  44.         {
  45.             #region Fields
  46.  
  47.             private readonly IEnumerable<T> source;
  48.  
  49.             #endregion
  50.  
  51.             #region Constructors
  52.  
  53.             public DynamicEnumerable(IEnumerable<T> source)
  54.             {
  55.                 this.source = source;
  56.             }
  57.  
  58.             #endregion
  59.  
  60.             #region Public Methods
  61.  
  62.             public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
  63.             {
  64.                 var match = methodMatcher.Match(binder.Name);
  65.                 if (match.Success)
  66.                 {
  67.                     var properties = match.Groups[2].Value.Split(new[] { "And" }, StringSplitOptions.RemoveEmptyEntries);
  68.                     var predicate = BuildExpression<T>(properties, args).Compile();
  69.  
  70.                     if (match.Groups[1].Success)
  71.                         result = source.Where(predicate);
  72.                     else
  73.                         result = source.FirstOrDefault(predicate);
  74.  
  75.                     return true;
  76.                 }
  77.                 return base.TryInvokeMember(binder, args, out result);
  78.             }
  79.  
  80.             #endregion
  81.         }
  82.  
  83.         private sealed class DynamicQueryable<T> : DynamicObject
  84.         {
  85.             #region Fields
  86.  
  87.             private readonly IQueryable<T> source;
  88.  
  89.             #endregion
  90.  
  91.             #region Constructors
  92.  
  93.             public DynamicQueryable(IQueryable<T> source)
  94.             {
  95.                 this.source = source;
  96.             }
  97.  
  98.             #endregion
  99.  
  100.             #region Public Methods
  101.  
  102.             public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
  103.             {
  104.                 var match = methodMatcher.Match(binder.Name);
  105.                 if (match.Success)
  106.                 {
  107.                     var properties = match.Groups[2].Value.Split(new[] { "And" }, StringSplitOptions.RemoveEmptyEntries);
  108.                     var predicate = BuildExpression<T>(properties, args);
  109.  
  110.                     if (match.Groups[1].Success)
  111.                         result = source.Where(predicate);
  112.                     else
  113.                         result = source.FirstOrDefault(predicate);
  114.  
  115.                     return true;
  116.                 }
  117.                 return base.TryInvokeMember(binder, args, out result);
  118.             }
  119.  
  120.             #endregion
  121.         }
  122.  
  123.         #endregion
  124.     }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×