internal IReadOnlyCollection <AnnotationResult> Validate(ValidationContext source) { Func <ValidationContext, IEnumerable <AnnotationResult> > validate = validable => { var property = validable.Path.OfType <Step>().Last().Property; return(property.GetCustomAttributes <ValidationAttribute>(true) .Select(attribute => new { Result = attribute.GetValidationResult(validable.Value, new BillGates.ValidationContext(source.Value) { MemberName = property.Name }), Attribute = attribute }) .Where(validation => ValidationResult.Success != validation.Result) .Select(validation => new AnnotationError(validation.Attribute, validation.Result.ErrorMessage)) .Select(error => error.For(validable.Path)).ToList().AsReadOnly()); }; Func <ValidationContext, IEnumerable <AnnotationResult> > stepInto = validable => { var current = validable.Value.GetType(); var enumerableOf = current.AsArgumentsOf(typeof(IEnumerable <>)).IfHasValue(args => args.Single()); if (enumerableOf != null && Consider.ForIteration(enumerableOf)) { var members = (validable.Value as IEnumerable).IfExists(e => e).OfType <object>().ToList(); return(members.Zip(Enumerable.Range(0, members.Count), (member, index) => validable.StepInto(index)) .Select(this.Validate) .SelectMany(results => results)); } return(Consider.ForIteration(current) ? this.Validate(validable) : null); }; var ms = new BillGates.ValidationContext(source.Value, new ServiceProvider(resolve), null); var errorsFromType = source.Value.IfExists(v => v.GetType()).GetCustomAttributes <CustomValidationAttribute>() .Where(rule => rule.GetValidationResult(source.Value, ms) != ValidationResult.Success) .Select(rule => new AnnotationError(rule, rule.FormatErrorMessage(source.Value.GetType().Name))) .Select(error => error.For(source.Path)).ToList(); var errors = source.Value.GetType().GetProperties() .Where(property => property.HasPublicGetter()) .Select(source.StepInto) .Aggregate(new List <AnnotationResult>(), (validators, validable) => validators.PushMany(validable.Value.IfExists(value => stepInto(validable)) ?? validate(validable))) .Concat(errorsFromType).ToList(); return(errors); }
/// <summary> /// Recursive injection based on the name conventions (case-insensitive). /// Reasonable type conversions are supported. /// </summary> /// <param name="source"></param> /// <param name="existing"></param> /// <returns></returns> internal static object InjectTo(this object source, object existing, CultureInfo culture) { if (source == null) { return(existing); } var dynamic = source.GetDynamicMetaObject(); object valueOf(string propertyName) { return(dynamic != null ? dynamic .GetDynamicMemberNames() .SingleOrDefault(name => string.Equals(name, propertyName, StringComparison.InvariantCultureIgnoreCase)) .IfExists(name => ((dynamic)source)[name]) : source.GetType() .GetProperty(propertyName, injectables | BindingFlags.IgnoreCase) .IfExists(property => property.GetValue(source))); } Func <PropertyInfo, object> recursively = target => { var value = valueOf(target.Name); var targetType = target.PropertyType; bool consider(Type type) => Consider.ForIteration(type) && !type.IsInterface && !type.IsAbstract; // first examine if a collection is about to be injected var memberType = targetType.AsArgumentsOf(typeof(IEnumerable <>)).IfHasValue(args => args.Single()); if (memberType != null && consider(memberType)) { var list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(memberType)); return((value as IEnumerable)?.OfType <object>() // only when the value exists and only for non-null members .Select(member => member.InjectTo(memberType)).OfType <object>() .Aggregate(list, (current, member) => { current.Add(member); return current; })); } // otherwise it is an injectable object or a single property: return(consider(targetType) ? value?.InjectTo(targetType, culture) : value?.ChangeType(targetType, culture)); }; return(existing.Inject(recursively)); }
public static TDynamicObject ToDynamic <TDynamicObject>(this object source) where TDynamicObject : DynamicObject, new() { if (source == null) { return(new TDynamicObject()); } var sourceType = source.GetType(); //Func<Type, bool> consider = type => type.Assembly == inputType.Assembly && !type.IsValueType; DynamicObject toDynamic(object from) { var fromType = from.GetType(); var memberType = fromType.AsArgumentsOf(typeof(IEnumerable <>)).IfHasValue(args => args.Single()); if (memberType != null && Consider.ForIteration(memberType)) { return((from as IEnumerable) .IfExists().OfType <object>() .Select(member => member.ToDynamic <TDynamicObject>()) .OfType <TDynamicObject>() .Aggregate(new CaseInsensitiveEnumerableExpando(), (list, member) => list.Push(member))); } return(Consider.ForIteration(fromType) ? from.ToDynamic <TDynamicObject>() : null); } //if (source.AsDynamic().HasValue) // return (TDynamicObject)source; // may crash return(sourceType .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(property => property.HasPublicGetter()) .Select(property => new { property.Name, Value = property.GetValue(source) }) .Where(property => property.Value != null) .Aggregate(new TDynamicObject(), (impl, property) => { var dynamic = impl as dynamic; dynamic[property.Name] = toDynamic(property.Value) ?? property.Value; return impl; })); }
public OBO_Typedef(List <KeyValuePair <string, string> > data = null) { if (data != null) { foreach (var datum in data) { switch (datum.Key.ToLower()) { case "id": Id = datum.Value; break; case "is_anonymous": IsAnonymous = Convert.ToBoolean(datum.Value); break; case "name": Name = datum.Value; break; case "namespace": Namespace = datum.Value; break; case "alt_id": AltId.Add(datum.Value); break; case "def": Def = datum.Value; break; case "comment": Comment = datum.Value; break; case "subset": Subset.Add(datum.Value); break; case "synonym": Synonym.Add(datum.Value); break; case "xref": XRef.Add(datum.Value); break; case "domain": Domain = datum.Value; break; case "range": Range = datum.Value; break; case "is_anti_symmetric": IsAntiSymmetric = Convert.ToBoolean(datum.Value); break; case "is_cyclic": IsCyclic = Convert.ToBoolean(datum.Value); break; case "is_reflexive": IsReflexive = Convert.ToBoolean(datum.Value); break; case "is_symmetric": IsSymmetric = Convert.ToBoolean(datum.Value); break; case "is_transitive": IsTransitive = Convert.ToBoolean(datum.Value); break; case "is_a": IsA.Add(datum.Value); break; case "inverse_of": InverseOf = datum.Value; break; case "transitive_over": TransitiveOver.Add(datum.Value); break; case "relationship": Relationship.Add(datum.Value); break; case "is_obsolete": IsObsolete = Convert.ToBoolean(datum.Value); break; case "replaced_by": ReplacedBy.Add(datum.Value); break; case "consider": Consider.Add(datum.Value); break; case "created_by": CreatedBy = datum.Value; break; case "creation_date": CreationDate = datum.Value; break; default: break; } } } }
public OBO_Instance(List <KeyValuePair <string, string> > data = null) { if (data != null) { foreach (var datum in data) { switch (datum.Key.ToLower()) { case "id": Id = datum.Value; break; case "is_anonymous": IsAnonymous = Convert.ToBoolean(datum.Value); break; case "name": Name = datum.Value; break; case "namespace": Namespace = datum.Value; break; case "alt_id": AltId.Add(datum.Value); break; case "comment": Comment = datum.Value; break; case "synonym": Synonym.Add(datum.Value); break; case "xref": XRef.Add(datum.Value); break; case "instance_of": InstanceOf = datum.Value; break; case "property_value": Property_Value.Add(datum.Value); break; case "is_obsolete": IsObsolete = Convert.ToBoolean(datum.Value); break; case "replaced_by": ReplacedBy.Add(datum.Value); break; case "consider": Consider.Add(datum.Value); break; default: break; } } } }
public OBO_Term(List <KeyValuePair <string, string> > data = null) { if (data != null) { foreach (var datum in data) { switch (datum.Key.ToLower()) { case "id": Id = datum.Value; break; case "is_anonymous": IsAnonymous = Convert.ToBoolean(datum.Value); break; case "name": Name = datum.Value; break; case "namespace": Namespace = datum.Value; break; case "alt_id": AltId.Add(datum.Value); break; case "def": Def = datum.Value; break; case "comment": Comment = datum.Value; break; case "subset": Subset.Add(datum.Value); break; case "synonym": Synonym.Add(datum.Value); break; case "xref": XRef.Add(datum.Value); break; case "is_a": IsA.Add(datum.Value); break; case "intersection_of": IntersectionOf.Add(datum.Value); break; case "union_of": UnionOf.Add(datum.Value); break; case "disjoint_from": DisjointFrom.Add(datum.Value); break; case "relationship": Relationship.Add(datum.Value); break; case "is_obsolete": IsObsolete = Convert.ToBoolean(datum.Value); break; case "replaced_by": ReplacedBy.Add(datum.Value); break; case "consider": Consider.Add(datum.Value); break; case "created_by": CreatedBy = datum.Value; break; case "creation_date": CreationDate = datum.Value; break; default: break; } } } }