/// <summary> /// Gets or sets the <see cref="System.Object"/> with the specified key. /// </summary> /// <value> /// The <see cref="System.Object"/>. /// </value> /// <param name="key">The key.</param> /// <returns></returns> public object this[string key] { get { if (this._keyedValues.TryGetValue(key, out object result)) { return(result); } var concreteDtoMetadata = metadataByDerivedType[this.GetType()]; if (concreteDtoMetadata .ReservedPropertyInfoByReservedKey .TryGetValue(key, out PropertyInfo reservedPropertyInfo)) { //if we have matching reserved property of value type - return default for it: if (reservedPropertyInfo.PropertyType.IsValueType) { return(Activator.CreateInstance(reservedPropertyInfo.PropertyType)); } } return(null); } set { Assumption.AssertTrue( !this._keyedValues.ContainsKey(key) || // no such key preset yet this._keyedValues[key] == null || // OR its not initialized yet value != null || // OR no-null value !this._metadata.ReservedPropertyInfoByReservedKey.Keys.Contains(key), // OR not about reserved property/key "conditional " + nameof(value) + " assessment" ); // var concreteDtoMetadata = metadataByDerivedType[this.GetType()]; if (concreteDtoMetadata .ReservedPropertyInfoByReservedKey .TryGetValue(key, out PropertyInfo reservedPropertyInfo)) { var reservedPropertyType = reservedPropertyInfo.PropertyType; var valueType = value?.GetType(); Assumption.AssertTrue( //we are not dealing with a reserved property, hence, anything works: !concreteDtoMetadata.ReservedPropertyInfoByReservedKey.ContainsKey(key) //OR we are dealing with a reserved property and the value and its type should make sense: || value == null || reservedPropertyType == valueType || (reservedPropertyType.IsInterface && ReflectionUtility.DoesTypeImplementInterface(valueType, reservedPropertyType)) || (reservedPropertyType.IsGenericType && // dealing with nullable type reservedPropertyType.GenericTypeArguments.Length == 1 && reservedPropertyType.GenericTypeArguments[0] == valueType) || valueType.IsSubclassOf(reservedPropertyType), nameof(value) ); } // this._keyedValues[key] = value; } }
public void TestDoesTypeImplementInterface() { var observedType = typeof(RollbarPackageBase); var interfaceOfInterest = typeof(IRollbarPackage); var result = ReflectionUtility.DoesTypeImplementInterface( observedType, interfaceOfInterest ); Assert.IsTrue(result); }
public object?this[string key] { get { if (this._keyedValues.TryGetValue(key, out var result)) { return(result); } var concreteDtoMetadata = metadataByDerivedType[this.GetType()]; if (concreteDtoMetadata.ReservedPropertyInfoByReservedKey == null) { return(null); } if (concreteDtoMetadata .ReservedPropertyInfoByReservedKey .TryGetValue(key, out var reservedPropertyInfo) && reservedPropertyInfo.PropertyType.IsValueType ) { return(Activator.CreateInstance(reservedPropertyInfo.PropertyType)); } return(null); } set { bool isReservedProperty = this._metadata?.ReservedPropertyInfoByReservedKey?.Keys.Contains(key) ?? false; Assumption.AssertTrue( !this._keyedValues.ContainsKey(key) || // no such key preset yet this._keyedValues[key] == null || // OR its not initialized yet value != null || // OR no-null value !isReservedProperty, // OR not about reserved property/key "conditional " + nameof(value) + " assessment" ); var lowCaseKey = key.ToLower(); var concreteDtoMetadata = metadataByDerivedType[this.GetType()]; if (concreteDtoMetadata.ReservedPropertyInfoByReservedKey != null && concreteDtoMetadata .ReservedPropertyInfoByReservedKey .TryGetValue(key, out PropertyInfo? reservedPropertyInfo)) { var reservedPropertyType = reservedPropertyInfo.PropertyType; var valueType = value?.GetType(); if (valueType != null) { Assumption.AssertTrue( //we are not dealing with a reserved property, hence, anything works: !(concreteDtoMetadata.ReservedPropertyInfoByReservedKey.ContainsKey(key) || concreteDtoMetadata.ReservedPropertyInfoByReservedKey.ContainsKey(lowCaseKey)) //OR we are dealing with a reserved property and the value and its type should make sense: || value == null || reservedPropertyType == valueType || (reservedPropertyType.IsInterface && ReflectionUtility.DoesTypeImplementInterface(valueType, reservedPropertyType)) || (reservedPropertyType.IsGenericType && // dealing with nullable type reservedPropertyType.GenericTypeArguments.Length == 1 && reservedPropertyType.GenericTypeArguments[0] == valueType) || valueType.IsSubclassOf(reservedPropertyType), nameof(value) ); } } if (concreteDtoMetadata.ReservedPropertyInfoByReservedKey != null && concreteDtoMetadata.ReservedPropertyInfoByReservedKey.ContainsKey(lowCaseKey)) { // we are setting a reserved key when calling Bind(...) on an IConfigurationSection // that treats this instance of ExtendableDtoBase as a dictionary while binding to the targeted deserialization object: this._keyedValues[lowCaseKey] = value; } else { this._keyedValues[key] = value; } } }