private ListFilter <T> Compile() { var uniqueCode = GetUniqueCode(); ListFilter <T> resultFilter; if (!FiltersCache.TryGetValue(uniqueCode, out resultFilter)) { var includeAssemblies = new HashSet <string>(); var provider = new CSharpCodeProvider(new Dictionary <string, string>() { { "CompilerVersion", "v3.5" } }); var name = "Filter"; if (FilterBy != null) { name += "_" + Regex.Replace(FilterBy, @"\W", ""); } if (SortFields != null) { name += "_Sort_" + Regex.Replace(SortFields.Aggregate((y, x) => y), @"\W", ""); } var typeName = provider.CreateValidIdentifier(name); var targetTypeName = typeof(T).FullName.Replace('+', '.'); var code = new StringBuilder(); code.AppendLine("using System;"); code.AppendLine("using System.Collections;"); code.AppendLine("using System.Collections.Generic;"); code.AppendLine("using System.Linq;"); code.AppendLine("using ASC.Api.Collections;"); code.AppendLine("using System.Globalization;"); code.AppendFormat("public class {1} : ListFilter<{0}> {{\r\n", targetTypeName, typeName); code.AppendFormat( " public override IEnumerable<{0}> FilterList(IEnumerable<{0}> items, bool sortDescending, FilterOperation operation, string[] filterValues){{\r\n", targetTypeName); //Do a needed operations //TODO: Do a null checks! if (ShouldFilter()) { try { var filters = FilterBy.Split(','); var filterChecks = new List <string>(); foreach (var filter in filters) { var propInfo = GetPropertyInfo(filter).Where(x => x != null).ToList(); foreach (var propertyInfo in propInfo) { includeAssemblies.Add(propertyInfo.PropertyType.Assembly.Location); } var byProperty = GetPropertyPath(propInfo); var nullCheck = GetNullCheck("item", propInfo); filterChecks.Add(string.Format("({1}Satisfy(operation, filterValues, item.{0}{2}))", byProperty, string.IsNullOrEmpty(nullCheck) ? "" : (nullCheck + " && "), GetPropertyToString(propInfo.Last()))); } code.AppendFormat( "items = items.Where(item =>{0});\r\n", string.Join(" || ", filterChecks.ToArray())); } catch (Exception) { } } if (ShouldSort()) { var propInfo = SortFields.Select(x => GetPropertyInfo(x)).Where(x => x != null).ToList(); //Add where if (propInfo.Any()) { foreach (var info in propInfo) { foreach (var propertyInfo in info) { includeAssemblies.Add(propertyInfo.PropertyType.Assembly.Location); } var nullCheck = GetNullCheck("item", info); if (!string.IsNullOrEmpty(nullCheck)) { code.AppendFormat("items=items.Where(item=>{0});", nullCheck); code.AppendLine(); } } var byProperties = propInfo.Select(x => GetPropertyPath(x)).ToList(); code.AppendLine("items = sortDescending"); code.AppendFormat("?items.OrderByDescending(item => item.{0})", byProperties.First()); foreach (var byProperty in byProperties.Skip(1)) { code.AppendFormat(".ThenByDescending(item => item.{0})", byProperty); } code.AppendFormat(": items.OrderBy(item => item.{0})", byProperties.First()); foreach (var byProperty in byProperties.Skip(1)) { code.AppendFormat(".ThenBy(item => item.{0})", byProperty); } code.AppendLine(";"); } } code.AppendFormat("return items;\r\n"); code.AppendLine("} }"); var assemblyName = "filter" + Guid.NewGuid().ToString("N"); var cp = new CompilerParameters { GenerateExecutable = false, OutputAssembly = assemblyName, GenerateInMemory = true, TreatWarningsAsErrors = false, CompilerOptions = "/optimize /t:library", IncludeDebugInformation = false, }; cp.ReferencedAssemblies.Add("mscorlib.dll"); cp.ReferencedAssemblies.Add("system.dll"); cp.ReferencedAssemblies.Add("System.Core.dll"); cp.ReferencedAssemblies.Add(GetType().Assembly.Location); cp.ReferencedAssemblies.Add(typeof(T).Assembly.Location); foreach (var includeAssembly in includeAssemblies) { cp.ReferencedAssemblies.Add(includeAssembly); } var cr = provider.CompileAssemblyFromSource(cp, code.ToString()); if (!cr.Errors.HasErrors) { var assembly = cr.CompiledAssembly; var evaluatorType = assembly.GetType(typeName); var evaluator = Activator.CreateInstance(evaluatorType); resultFilter = evaluator as ListFilter <T>; } //Add anyway!!! FiltersCache.Add(uniqueCode, resultFilter); } return(resultFilter); }