public DbBook Convert(IScraper scraper, IServiceProvider services) { var book = new DbBook().ApplyBase(ModelSanitizer.Sanitize(Book), services); book.Contents = (Contents ?? Enumerable.Empty <ContentAdaptor>()).ToArray(c => { var content = new DbBookContent().ApplyBase(ModelSanitizer.Sanitize(c.Content), services); content.PageCount = c.Pages; content.Source = scraper.Type; content.SourceId = c.Id; content.Data = c.Data; return(content); }); return(book); }
public DbBook Convert(IScraper scraper, IServiceProvider services) { var book = new DbBook().ApplyBase(ModelSanitizer.Sanitize(Book), services); book.Contents = (Contents ?? Enumerable.Empty<ContentAdaptor>()).ToArray(c => { var content = new DbBookContent().ApplyBase(ModelSanitizer.Sanitize(c.Content), services); content.PageCount = c.Pages; content.Source = scraper.Type; content.SourceId = c.Id; content.Data = c.Data; content.IsAvailable = true; content.RefreshTime = DateTime.UtcNow; return content; }); return book; }
public ComplexTypeSanitizer() { var type = typeof(T); var param = Expression.Parameter(type, "value"); var body = new List <Expression>(); // before sanitize callback if (typeof(ISanitizableObject).IsAssignableFrom(type)) { body.Add(Expression.Call(param, ISanitizableObject.BeforeSanitizeMethod)); } var paramAttrs = type.GetCustomAttributes().OfType <SanitizerAttribute>().ToArray(); // before sanitize attributes body.AddRange(paramAttrs.Select(a => Expression.Assign(param, Expression.Convert(Expression.Call(Expression.Constant(a), SanitizerAttribute.BeforeSanitizeMethod, Expression.Convert(param, typeof(object))), type)))); foreach (var property in type.GetProperties().Where(p => p.CanRead && p.CanWrite)) { // skip on ignore attribute if (property.IsDefined(typeof(SanitizerIgnoreAttribute), true)) { continue; } var target = Expression.Property(param, property); var propertyAttrs = property.GetCustomAttributes().OfType <SanitizerAttribute>().ToArray(); // before sanitize attributes on property body.AddRange(propertyAttrs.Select(a => Expression.Assign(target, Expression.Convert(Expression.Call(Expression.Constant(a), SanitizerAttribute.BeforeSanitizeMethod, Expression.Convert(target, typeof(object))), property.PropertyType)))); // property sanitizer var sanitizer = ModelSanitizer.GetSanitizer(property.PropertyType); var sanitizeMethod = sanitizer.GetType().GetMethod(nameof(Sanitize)); if (!(sanitizer is IEmptySanitizer) && sanitizeMethod != null) { body.Add(Expression.Assign(target, Expression.Call(Expression.Constant(sanitizer), sanitizeMethod, target))); } // after sanitize attributes on property body.AddRange(propertyAttrs.Select(a => Expression.Assign(target, Expression.Convert(Expression.Call(Expression.Constant(a), SanitizerAttribute.AfterSanitizeMethod, Expression.Convert(target, typeof(object))), property.PropertyType)))); } // after sanitize attributes body.AddRange(paramAttrs.Select(a => Expression.Assign(param, Expression.Convert(Expression.Call(Expression.Constant(a), SanitizerAttribute.AfterSanitizeMethod, Expression.Convert(param, typeof(object))), type)))); // after sanitize callback if (typeof(ISanitizableObject).IsAssignableFrom(type)) { body.Add(Expression.Call(param, ISanitizableObject.AfterSanitizeMethod)); } // return value expression body.Add(param); var lambda = Expression.Lambda <Func <T, T> >(Expression.Block(body), param); ModelSanitizer.OnExpressionBuilt?.Invoke(lambda); _sanitize = lambda.CompileFast(); }