public override void GenerateFilterIl(System.Reflection.Emit.ILGenerator generator, Dictionary<string, string> filterValues, PropertyInfo property) { MethodInfo StringToLower = typeof(string).GetMethod("ToLower", new Type[] { }); MethodInfo StringStartsWith = typeof(String).GetMethod("StartsWith", new Type[] { typeof(string) }); MethodInfo StringContains = typeof(String).GetMethod("Contains", new Type[] { typeof(string) }); MethodInfo StringIsNullOrWhiteSpace = typeof(string).GetMethod("IsNullOrWhiteSpace", new Type[] { typeof(string) }); Label lblNextProperty = generator.DefineLabel(); Label lblNotNull = generator.DefineLabel(); string filterText = filterValues["filterText"]; string filterMode = filterValues["filterMode"]; // Do nothing for this property is the filterText is blank and the filterMode is "Starts With", "Doesn't Start With", "Contains", or " Doesn't Contain" if (string.IsNullOrWhiteSpace(filterText) && new string[] { "Starts With", "Doesn't Start With", "Contains", "Doesn't Contain" }.Contains(filterMode)) return; switch (filterMode) { case "Starts With": case "Contains": // Check that the property is not null. If it is null, return false; otherwise, continue. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Brtrue, lblNotNull); generator.EmitReturnFalse(); generator.MarkLabel(lblNotNull); // Load the property of the argument and make it lower-case. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Callvirt, StringToLower); // Load the lower-cased search key and see if the lower-cased property starts with it. generator.Emit(OpCodes.Ldstr, filterText.ToLower()); // We use either String.StartsWith or String.Contains according to what the user specified. generator.Emit(OpCodes.Callvirt, filterMode == "Starts With" ? StringStartsWith : StringContains); // If the search key doesn't match, then return false; otherwise, go on to the next property generator.Emit(OpCodes.Brtrue, lblNextProperty); generator.EmitReturnFalse(); break; case "Doesn't Start With": case "Doesn't Contain": // Check that the property is not null. If it is null, then go on to the next property. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Brfalse, lblNextProperty); // Load the property of the argument and make it lower-case. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Callvirt, StringToLower); // Load the lower-cased search key and see if the lower-cased property starts with it. generator.Emit(OpCodes.Ldstr, filterText.ToLower()); // We use either String.StartsWith or String.Contains according to what the user specified. generator.Emit(OpCodes.Callvirt, filterMode == "Starts With" ? StringStartsWith : StringContains); // Since we're doing the opposite of the "Starts With" and "Contains" cases, go to the next property // if the search key doesn't match, and return false otherwise. generator.Emit(OpCodes.Brfalse, lblNextProperty); generator.EmitReturnFalse(); break; case "Is Blank": // Load the property of the argument and see if it's null or whitespace generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Call, StringIsNullOrWhiteSpace); // If we didn't get back true, then return false; otherwise, go on to the next property. generator.Emit(OpCodes.Brtrue, lblNextProperty); generator.EmitReturnFalse(); break; case "Isn't Blank": // Load the property of the argument and see if it's null or whitespace generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Call, StringIsNullOrWhiteSpace); // If we didn't get back false, then return false; otherwise, go on to the next property. generator.Emit(OpCodes.Brfalse, lblNextProperty); generator.EmitReturnFalse(); break; } generator.MarkLabel(lblNextProperty); }
public override void GenerateFilterIl(System.Reflection.Emit.ILGenerator generator, Dictionary<string, string> filterValues, PropertyInfo property) { string minDateString = filterValues["minDate"]; string maxDateString = filterValues["maxDate"]; bool isNullable = property.PropertyType.Name == "Nullable`1"; Label lblNextProperty = generator.DefineLabel(); Label lblReturnFalse = generator.DefineLabel(); // First, get the value loaded, but if it is null, then return false unless both minDate and maxDate are blank. if (isNullable) { // This block of code is so-far UNTESTED!!! MethodInfo GetNullableHasValue = typeof(DateTime?).GetProperty("HasValue").GetGetMethod(); MethodInfo GetNullableValue = typeof(DateTime?).GetProperty("Value").GetGetMethod(); bool minAndMaxBothBlank = string.IsNullOrWhiteSpace(minDateString) && string.IsNullOrWhiteSpace(maxDateString); Label whereToGoIfNull = minAndMaxBothBlank ? lblNextProperty : lblReturnFalse; // If the property is null and both min and max date are blank, then go to the next property. // If the property is null and either min or max date has a value, return false. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Stloc, nullableDateTimeStorage); generator.Emit(OpCodes.Ldloca_S, nullableDateTimeStorage); generator.Emit(OpCodes.Call, GetNullableHasValue); generator.Emit(OpCodes.Brfalse_S, whereToGoIfNull); // If we haven't jumped, then the datetime is not null, so just save it. generator.Emit(OpCodes.Ldloca_S, nullableDateTimeStorage); generator.Emit(OpCodes.Call, GetNullableValue); generator.Emit(OpCodes.Stloc, dateTimeStorage); } else // not nullable { // The property is not nullable, so just save the value. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Stloc, dateTimeStorage); } // At this point, the record's datetime should be saved in memory. MethodInfo DateTimeParse = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) }); MethodInfo DateTimeLessThanOrEqual = typeof(DateTime).GetMethod("op_LessThanOrEqual"); MethodInfo DateTimeGreaterThanOrEqual = typeof(DateTime).GetMethod("op_GreaterThanOrEqual"); if (!string.IsNullOrWhiteSpace(minDateString)) { generator.Emit(OpCodes.Ldstr, minDateString); generator.Emit(OpCodes.Call, DateTimeParse); // Get the mindate DateTime. generator.Emit(OpCodes.Ldloc, dateTimeStorage); // Get the record's DateTime from memory generator.Emit(OpCodes.Call, DateTimeLessThanOrEqual); generator.Emit(OpCodes.Brfalse, lblReturnFalse); } if (!string.IsNullOrWhiteSpace(maxDateString)) { generator.Emit(OpCodes.Ldstr, maxDateString); generator.Emit(OpCodes.Call, DateTimeParse); // Get the maxdate DateTime. generator.Emit(OpCodes.Ldloc, dateTimeStorage); // Get the record's DateTime from memory generator.Emit(OpCodes.Call, DateTimeGreaterThanOrEqual); generator.Emit(OpCodes.Brfalse, lblReturnFalse); } generator.Emit(OpCodes.Br, lblNextProperty); generator.MarkLabel(lblReturnFalse); generator.EmitReturnFalse(); generator.MarkLabel(lblNextProperty); }