/// <summary> /// Gets the value of an open property /// </summary> /// <param name="value">The instance to get the property value from</param> /// <param name="propertyName">The open property name</param> /// <returns>The open property's value</returns> public virtual object GetValue(object value, string propertyName) { ExceptionUtilities.CheckArgumentNotNull(value, "value"); ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName"); // for sub-values of a complex type inside an open property, GetValue will still be used // so we should check before calling GetOpenPropertyValue (which will throw on non-open types) ResourceType type = this.GetResourceType(value); ExceptionUtilities.CheckObjectNotNull(type, "GetValue called with object of unknown type. Type was '{0}'", value.GetType()); if (type.IsOpenType) { return(this.QueryProvider.GetOpenPropertyValue(value, propertyName)); } ExceptionUtilities.Assert(type.ResourceTypeKind == ResourceTypeKind.ComplexType, "OpenTypeMethods.GetValue used on non-open, non-complex type '{0}'", type.FullName); ResourceProperty resourceProperty = type.GetAllPropertiesLazily().SingleOrDefault(p => p.Name == propertyName); ExceptionUtilities.CheckObjectNotNull(resourceProperty, "OpenTypeMethods.GetValue used on non-open type '{0}' with non-existent property '{1}'", type.FullName, propertyName); return(this.QueryProvider.GetPropertyValue(value, resourceProperty)); }