private IEnumerable <TObject> FilterResponseRecordsByDynamicInternal(Tuple <Property, object> filter, IEnumerable <TObject> records) { //Get the PropertyInfo the filter Property corresponds to. var property = ReflectionCacheManager.Get(typeof(TObject)) .Properties .First( p => p.GetAttribute <PropertyParameterAttribute>()?.Property.Equals(filter.Item1) == true ); if (property.Property.PropertyType.IsArray) { throw new NotImplementedException("Cannot filter array properties dynamically"); } //Was the value that was specified enumerable? The answer should always be yes, as //DynamicParameterPropertyTypes only defines array types if (filter.Item2.IsIEnumerable()) { //Get the values that were specified var values = GetDynamicWildcardFilterValues(filter); return(FilterResponseRecordsByWildcardArray(values, r => { if (typeof(IStringEnum).IsAssignableFrom(property.Property.PropertyType)) { return ((IStringEnum)property.Property.GetValue(r)).StringValue; } return property.Property.GetValue(r).ToString(); }, records)); } throw new NotImplementedException($"All PropertyInfo values should be array types, however type {filter.Item2.GetType().FullName} was not"); }
private IEnumerable <NotificationTrigger> FilterByDynamicParameters(IEnumerable <NotificationTrigger> triggers) { if (dynamicParameterSet != null) { //Our NotificationAction parameters are defined as "real" parameters, so we will filter on them elsewhere, //not that it matters however, as they too don't support filtering where their values are null var boundParameters = dynamicParameterSet.GetBoundParameters(this, Tuple.Create).Where(t => t.Item2 != null); foreach (var parameter in boundParameters) { //Get the PropertyInfo the filter Property corresponds to. var property = ReflectionCacheManager.Get(typeof(NotificationTrigger)).Properties.First(p => p.GetAttribute <PropertyParameterAttribute>()?.Property.Equals(parameter.Item1) == true); if (property.Property.PropertyType.IsArray) { throw new NotImplementedException("Cannot filter array properties dynamically."); } var items = parameter.Item2.ToIEnumerable().ToList(); triggers = triggers.Where(t => items.Any(i => Equals(property.GetValue(t), i))); } } return(triggers); }
/// <summary> /// Creates dynamic parameters for all parameters defined on a <see cref="NewSensorParameters"/> object. /// </summary> /// <param name="dictionary">The dynamic parameters dictionary to add parameters to.</param> private void AddParametersObjectDynamicParameters(RuntimeDefinedParameterDictionaryEx dictionary) { //If TypeAttribute.Class is null (i.e. creating the parameters are not actually supported) a SwitchParameter wouldn't have been created //and we won't actually get to this point var parametersType = Type.GetEnumAttribute <TypeAttribute>(true); var properties = ReflectionCacheManager.Get(parametersType.Class).Properties.Where(p => p.GetAttribute <PropertyParameterAttribute>() != null); var parameterConfig = Type.GetEnumAttribute <NewSensorAttribute>() ?? new NewSensorAttribute(); int?position = null; foreach (var property in properties) { var parameterAttributes = new List <Attribute>(); var isNameParameter = property.Property.Name == nameof(NewObjectParameters.Name); position = GetPosition(property, isNameParameter, parameterConfig, position); foreach (var set in ParameterSets.Where(s => PropertyIsAllowedInSet(property, s))) { parameterAttributes.Add(new ParameterAttribute { Mandatory = GetMandatory(property, isNameParameter, parameterConfig), Position = position.Value, ParameterSetName = $"{Type}{set.Name}" }); } var name = GetParameterName(property); var type = property.Property.PropertyType; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>)) { var underlying = type.GetGenericArguments()[0]; type = underlying.MakeArrayType(); } dictionary.AddOrMerge(name, type, parameterAttributes.ToArray()); if (alternateSet != null) { IAlternateParameter alternateParameter; if (TryGetAlternateProperty(property, alternateSet.Name, out alternateParameter)) { var parameterAttribute = new ParameterAttribute { Mandatory = HasRequireValueTrue(property), Position = position.Value, ParameterSetName = $"{Type}{alternateSet.Name}" }; dictionary.AddOrMerge(alternateParameter.Name, alternateParameter.Type, parameterAttribute); } } } }
private ParameterSetDescriptor[] GetParameterSets() { if (makeCmdlet == null) { var setDescriptors = new List <ParameterSetDescriptor>(); setDescriptors.Add(new ParameterSetDescriptor(ParameterSet.PropertyManual)); if (alternateSet != null) { setDescriptors.Add(new ParameterSetDescriptor(alternateSet.Name, false, GetAlternateSetExcludedParameters())); } return(setDescriptors.ToArray()); } if (invoker == null) { Debug.Fail($"Invoker cannot be null in {nameof(GetParameterSets)} when {nameof(makeCmdlet)} is not null"); } //Get all the parameter sets defined on the cmdlet that will be invoked var cmdletProperties = ReflectionCacheManager.Get(invoker.CmdletToInvoke.GetType()).Properties .Where(p => p.GetAttribute <ParameterAttribute>() != null).ToList(); var sets = cmdletProperties .SelectMany(p => p.GetAttributes <ParameterAttribute>()) .Select(a => a.ParameterSetName) .Where(n => n != ParameterAttribute.AllParameterSets) .Distinct() .Select(s => { if (Type == SensorType.Factory) { return(new ParameterSetDescriptor(s, true, ObjectProperty.ChannelDefinition)); } else { throw new NotImplementedException($"Don't know what cmdlet based parameter set descriptor to use for sensor type '{Type}'."); } }) .ToList(); if (alternateSet != null) { sets.Add(new ParameterSetDescriptor(alternateSet.Name)); } //Normal set not utilizing any cmdlet parameters sets.Add(new ParameterSetDescriptor(ParameterSet.PropertyManual)); return(sets.ToArray()); }
internal static object XmlToEnum(string value, Type type, Type attribType, bool requireValue = true, bool allowFlags = true, bool allowParse = true, bool allowNumeric = false) { var enumXmlCache = ReflectionCacheManager.GetEnumXml(type); var val = enumXmlCache.Cache.GetValue(value, attribType); if (val != null) { return(val); } if (!allowParse) { return(null); } try { var underlying = Nullable.GetUnderlyingType(type); if (underlying != null) { type = underlying; } //todo: make this a tryparse, and then reparse and throw if we failed to parse var e = Enum.Parse(type, value, true); if (allowFlags == false && ((Enum)e).GetUnderlyingFlags().Any()) { return(null); } if (!allowNumeric && e.ToString().ToLower() != value.ToLower()) { return(null); } return(e); } catch { if (requireValue) { throw; } return(null); } }
private void BindParametersAndAddSensor(SensorParametersInternal parameters, bool endOperation) { //Bind all parameter properties that were specified var properties = ReflectionCacheManager.Get(parameters.GetType()).Properties.Where(p => p.GetAttribute <PropertyParameterAttribute>() != null); foreach (var property in properties) { object propertyValue; var propertyName = property.Property.Name; string pluralName; //Get the de-pluralized name of the property if (NewSensorDynamicParameterCategory.pluralMap.TryGetValue(propertyName, out pluralName)) { propertyName = pluralName; } //Was the de-pluralized name specified? If not, how about the sensor target replacement for the original pluralized name? if (MyInvocation.BoundParameters.TryGetValue(propertyName, out propertyValue)) { propertyValue = MaybeRewrapList(property, propertyValue); modifiedSensorParameters.Add(Tuple.Create(propertyName, propertyValue)); property.SetValue(parameters, propertyValue); } else { var name = property.Property.Name; if (dynamicParams.ActiveSensorType.TryGetSensorTarget(this, client, ref name, ref propertyValue)) { propertyValue = MaybeRewrapList(property, propertyValue); modifiedSensorParameters.Add(Tuple.Create(name, propertyValue)); propertyValue = CastSensorTarget(property.Property.PropertyType, (List <object>)propertyValue); property.SetValue(parameters, propertyValue); } } } dynamicParams.ActiveSensorType.ValidateParameters(this, parameters); ParametersInternal = parameters; AddObjectInternal(DestinationId, endOperation); }
public static Func <T, object> ToMemberAccessLambda <T>(Property property) { var typeProps = ReflectionCacheManager.Get(typeof(T)).Properties; var propertyCache = typeProps.First( p => p.GetAttributes <PropertyParameterAttribute>().Any(a => a.Property.Equals(property)) ); var obj = Expression.Parameter(typeof(T)); var memberAccess = Expression.MakeMemberAccess(obj, propertyCache.Property); var lambda = Expression.Lambda <Func <T, object> >(Expression.Convert(memberAccess, typeof(object)), obj); return(lambda.Compile()); }
public void BindParameters(Dictionary <string, object> boundParameters) { var properties = ReflectionCacheManager.Get(Cmdlet.GetType()).Properties.Where(p => p.GetAttribute <ParameterAttribute>() != null); foreach (var property in properties) { object propertyValue; var description = property.GetAttribute <DescriptionAttribute>(); if ((description != null && boundParameters.TryGetValue(description.Description, out propertyValue)) || boundParameters.TryGetValue(property.Property.Name, out propertyValue)) { property.SetValue(Cmdlet, propertyValue); } } }
private Expression MakeEnumLambda(Type type) { var p = Expression.Parameter(typeof(string), "s"); var c = ReflectionCacheManager.GetEnumCache(type).Cache; var fields = c.Fields; List <SwitchCase> cases = new List <SwitchCase>(); foreach (var f in fields) { if (f.Field.FieldType.IsEnum) { var val = f.Field.GetValue(null); var caseConditions = f.Attributes.Where(v => v.Key == typeof(XmlEnumAttribute) || v.Key == typeof(XmlEnumAlternateName)) .SelectMany(a => a.Value).Cast <XmlEnumAttribute>().Select(a => Expression.Constant(a.Name)).ToArray(); if (caseConditions.Length > 0) { cases.Add(Expression.SwitchCase(Expression.Constant(val), caseConditions)); } } } var failEnum = XmlExpressionConstants.FailEnum(p, type); var throwFailEnum = Expression.Throw(failEnum, type); Expression switchBody; if (cases.Count > 0) { switchBody = Expression.Switch(p, throwFailEnum, cases.ToArray()); } else { switchBody = throwFailEnum; } var lambda = Expression.Lambda( Expression.Block(switchBody), $"Read{type.Name}", new[] { p, XmlExpressionConstants.Serializer }); return(XmlSerializerGenerator.LambdaOrDelegate(lambda)); }
/// <summary> /// Retrieves an object that defines the dynamic parameters of this cmdlet. /// </summary> /// <returns>An object that defines the dynamic parameters of this cmdlet.</returns> public object GetDynamicParameters() { if (dynamicParameterSet == null) { var properties = ReflectionCacheManager.Get(typeof(NotificationTrigger)).Properties. Where(p => p.GetAttribute <PropertyParameterAttribute>() != null). Select(p => Tuple.Create((TriggerProperty)p.GetAttribute <PropertyParameterAttribute>().Property, p)).ToList(); dynamicParameterSet = new PropertyDynamicParameterSet <TriggerProperty>( new[] { ParameterSet.Dynamic, ParameterSet.DynamicManual }, e => ReflectionCacheManager.GetArrayPropertyType(properties.FirstOrDefault(p => p.Item1 == e)?.Item2.Property.PropertyType), this ); } return(dynamicParameterSet.Parameters); }
private void ValidateMandatoryParameters(Dictionary <string, object> boundParameters, string parameterSetName, Dictionary <object, object> dict) { var properties = ReflectionCacheManager.Get(GetType()).Properties.Where(p => p.GetAttribute <ParameterAttribute>() != null).ToList(); var required = properties.Select( p => Tuple.Create( p.Property.Name, p.GetAttributes <ParameterAttribute>().Where(a => a.ParameterSetName == parameterSetName && a.Mandatory).FirstOrDefault() ) ).Where(t => t.Item2 != null).Select(t => t.Item1).ToArray(); var missing = required.Except(boundParameters.Keys).ToArray(); if (missing.Length > 0) { throw new ParameterBindingException($"Cannot process hashtable '{PrettyPrintHashtable(dict)}' on parameter set '{parameterSetName}': parameter '{missing[0]}' is mandatory."); } }
private object Deserialize(Type type, object obj, XElement elm, params string[] properties) { var mappings = ReflectionCacheManager.Map(type); if (properties != null && properties.Length > 0) { mappings = mappings.Where(m => properties.Any(p => m.AttributeValue.Any(v => v == p))).ToList(); } foreach (var mapping in mappings) { Logger.Debug($"\nDeserialize property {mapping.PropertyCache.Property.Name}: "); try { switch (mapping.AttributeType) { case XmlAttributeType.Element: ProcessXmlElement(obj, mapping, elm); break; case XmlAttributeType.Attribute: ProcessXmlAttribute(obj, mapping, elm); break; case XmlAttributeType.Text: ProcessXmlText(obj, mapping, elm); break; default: throw new NotSupportedException(); //todo: add an appropriate failure message } } catch (Exception) { //throw new Exception("An error occurred while trying to deserialize property " + mapping.Property.Name); throw; } } Logger.Debug("\n"); return(obj); }
internal static object XmlToEnum(string value, Type type, Type attribType, bool requireValue = true, bool allowFlags = true, bool allowParse = true) { var val = ReflectionCacheManager.GetEnumXml(type).GetValue(value, attribType); if (val != null) { return(val); } if (!allowParse) { return(null); } try { var underlying = Nullable.GetUnderlyingType(type); if (underlying != null) { type = underlying; } var e = Enum.Parse(type, value, true); if (allowFlags == false && ((Enum)e).GetUnderlyingFlags().Any()) { return(null); } return(e); } catch { if (requireValue) { throw; } return(null); } }
private LambdaExpression MakeSwitchLambda(ParameterExpression property, ParameterExpression rawValue) { var c = ReflectionCacheManager.GetEnumCache(propertyType).Cache; var fields = c.Fields; List <SwitchCase> cases = new List <SwitchCase>(); foreach (var f in fields) { if (f.Field.FieldType.IsEnum) { var val = f.Field.GetValue(null); Expression body = GetCaseBody((Enum)val, rawValue); if (body != null) { if (body.NodeType != ExpressionType.Block) { body = Expression.Convert(body, typeof(object)); } cases.Add(Expression.SwitchCase(body, Expression.Constant(val))); } } } var @default = Expression.Constant(null); var assignName = XmlExpressionConstants.Serializer_Name(XmlAttributeType.Element).Assign(property.Call("ToString").Call("ToLower")); var @switch = Expression.Switch(property, @default, cases.ToArray()); return(Expression.Lambda( Expression.Block( assignName, @switch ), "ReadObjectPropertyInner", new[] { XmlExpressionConstants.Serializer, property, rawValue })); }
public Func <T, bool> Convert <T>() { var parameter = Expression.Parameter(typeof(T), "o"); var conditions = new List <Tuple <Property, Expression> >(); foreach (var filter in filters) { var typeProps = ReflectionCacheManager.Get(typeof(T)).Properties; var property = typeProps.FirstOrDefault( p => p.GetAttributes <PropertyParameterAttribute>().Any(a => a.Property.Equals(filter.Property)) ); if (property == null) { continue; } var member = Expression.MakeMemberAccess(parameter, property.Property); if (filter.Value is IEnumerable && !(filter.Value is string)) { foreach (var value in (IEnumerable)filter.Value) { conditions.AddRange(GetConditions(member, filter.Property, filter.Operator, value)); } } else { conditions.AddRange(GetConditions(member, filter.Property, filter.Operator, filter.Value)); } } var body = GetLambdaBody(conditions); var lambda = Expression.Lambda <Func <T, bool> >(body, parameter); var result = lambda.Compile(); return(result); }
internal object GetDynamicParameters(params string[] parameterSets) { if (parameterSets.Length == 0) { parameterSets = new[] { ParameterSet.Dynamic } } ; if (dynamicParameterSet == null) { var properties = ReflectionCacheManager.Get(typeof(TObject)).Properties. Where(p => p.GetAttribute <PropertyParameterAttribute>() != null). Select(p => Tuple.Create((Property)p.GetAttribute <PropertyParameterAttribute>().Property, p)).ToList(); dynamicParameterSet = new DynamicParameterSet <Property>( parameterSets, e => ReflectionCacheManager.GetArrayPropertyInfo(properties.FirstOrDefault(p => p.Item1 == e)?.Item2.Property.PropertyType), this ); } return(dynamicParameterSet.Parameters); }
private object GetValue(XObject mandatory, PropertyCache propertyCache, object value, XElement elm) { var final = mandatory == null ? null : GetValueInternal(propertyCache.Property.PropertyType, value, elm); var attrib = propertyCache.GetAttribute <PropertyParameterAttribute>(); if (attrib != null) { Enum prop; if (ReflectionCacheManager.GetEnumName(typeof(Property)).Cache.NameCache.TryGetValue(attrib.Name, out prop)) { var converter = prop.GetEnumFieldCache().GetAttributes <ValueConverterAttribute>().FirstOrDefault(); if (converter != null) { return(converter.Converter.Deserialize(final)); } } } return(final); }
private IEnumerable <NotificationTrigger> FilterByDynamicParameters(IEnumerable <NotificationTrigger> triggers) { if (dynamicParameterSet != null) { var boundParameters = dynamicParameterSet.GetBoundParameters(this, Tuple.Create); foreach (var parameter in boundParameters) { //Get the PropertyInfo the filter Property corresponds to. var property = ReflectionCacheManager.Get(typeof(NotificationTrigger)).Properties.First(p => p.GetAttribute <PropertyParameterAttribute>()?.Property.Equals(parameter.Item1) == true); if (property.Property.PropertyType.IsArray) { throw new NotImplementedException("Cannot filter array properties dynamically."); } var items = parameter.Item2.ToIEnumerable().ToList(); triggers = triggers.Where(t => items.Any(i => Equals(property.GetValue(t), i))); } } return(triggers); }
private void AddCmdletDynamicParameters(NewSensor newSensorCmdlet, RuntimeDefinedParameterDictionaryEx dictionary) { var properties = ReflectionCacheManager.Get(GetInvoker(newSensorCmdlet).CmdletToInvoke.GetType()).Properties .Where(p => p.GetAttribute <ParameterAttribute>() != null).ToList(); var highestPosition = GetHighestParameterPosition(dictionary); foreach (var property in properties) { var description = property.GetAttribute <DescriptionAttribute>(); var name = description?.Description ?? property.Property.Name; //Not cached so we can modify it var attributes = Attribute.GetCustomAttributes(property.Property, typeof(ParameterAttribute)).ToList(); foreach (ParameterAttribute attribute in attributes) { attribute.ParameterSetName = $"{Type}{attribute.ParameterSetName}"; if (attribute.Position >= 0 && highestPosition != null) { attribute.Position += highestPosition.Value + 1; } } var aliases = property.GetAttribute <AliasAttribute>(); if (aliases != null && !aliases.AliasNames.Contains(name)) { attributes.Add(aliases); } dictionary.AddOrMerge(name, property.Property.PropertyType, attributes.ToArray()); } }
internal static List <XmlMapping> GetMappings(Type type) { var properties = ReflectionCacheManager.Get(type).Properties; var mappings = new List <XmlMapping>(); foreach (var prop in properties) { if (FindXmlAttribute <XmlElementAttribute>(prop, mappings, type, a => a.ElementName, XmlAttributeType.Element)) { continue; } if (FindXmlAttribute <XmlAttributeAttribute>(prop, mappings, type, a => a.AttributeName, XmlAttributeType.Attribute)) { continue; } if (FindXmlAttribute <XmlTextAttribute>(prop, mappings, type, a => null, XmlAttributeType.Text)) { continue; } } return(mappings); }
private Expression GetCaseBody(Enum property, Expression rawValue) { var viaObject = false; var typeLookup = property.GetEnumAttribute <TypeLookupAttribute>()?.Class; //ObjectPropertyInternal members don't necessarily have a type lookup if (typeLookup == null) { return(null); } var mappings = ReflectionCacheManager.Map(typeLookup).Cache; var cache = ObjectPropertyParser.GetPropertyInfoViaTypeLookup(property); var xmlElement = cache.GetAttribute <XmlElementAttribute>(); //todo: what if this objectproperty doesnt point to a member with an xmlelementattribute? XmlMapping mapping = null; if (xmlElement != null) { mapping = mappings.FirstOrDefault(m => m.AttributeValue[0] == xmlElement.ElementName); } else { var mergeAttribute = property.GetEnumAttribute <MergeableAttribute>(); //If we're a property like LocationName, we don't exist server side - we're only used for constructing requests if (mergeAttribute != null) { return(null); } //We have a property like Interval which uses a backing property instead. //Get the backing property so that we may extract the real value from the public //property var rawName = ObjectPropertyParser.GetObjectPropertyNameViaCache(property, cache); var elementName = $"{HtmlParser.DefaultPropertyPrefix}{rawName.TrimEnd('_')}"; mapping = mappings.FirstOrDefault(m => m.AttributeValue[0] == elementName); if (mapping != null) { viaObject = true; } } if (mapping != null) { var deserializer = new ValueDeserializer(mapping, null, rawValue); var result = deserializer.Deserialize(); if (viaObject) { //Construct an expression like return new TableSettings { intervalStr = "60|60 seconds" }.Interval; var settingsObj = Expression.Variable(typeLookup, "obj"); var assignObj = settingsObj.Assign(Expression.New(typeLookup)); var internalProp = Expression.MakeMemberAccess(settingsObj, mapping.PropertyCache.Property); var assignInternal = internalProp.Assign(result); var externalProp = Expression.MakeMemberAccess(settingsObj, cache.Property); return(Expression.Block( new[] { settingsObj }, assignObj, assignInternal, Expression.Convert(externalProp, typeof(object)) )); } return(result); } //Property is not deserializable return(null); }
public static TypeCache GetTypeCache(this Type type) => ReflectionCacheManager.GetTypeCache(type).Cache;
public static CacheValue <TypeCache> GetTypeCache(this Type type) => ReflectionCacheManager.GetTypeCache(type);
public static TypeCache GetTypeCache(this object obj) => ReflectionCacheManager.Get(obj.GetType());
private void GetStaticParameters() { staticParameters = ReflectionCacheManager.Get(excludeStaticParameters.GetType()).Properties .Where(p => p.GetAttribute <ParameterAttribute>() != null) .Select(p => p.Property.Name).ToArray(); }
public static EnumCache GetEnumTypeCache(this Enum value) => (EnumCache)ReflectionCacheManager.Get(value.GetType());
public static FieldCache GetEnumFieldCache(this Enum value) => ReflectionCacheManager.GetEnumFieldCache(value);
public static TAttribute[] GetAttributes <TAttribute>(this PropertyInfo info) where TAttribute : Attribute => ReflectionCacheManager.Get(info.ReflectedType).Properties.First(p => p.Property == info).GetAttributes <TAttribute>();
public TestReflection2() { cacheManager = new ReflectionCacheManager(this); }