internal static void SetValue <TInterface, TProperty>(IProductElement target, Expression <Func <TProperty> > propertyExpresion, TProperty value)
        {
            Guard.NotNull(() => target, target);
            Guard.NotNull(() => propertyExpresion, propertyExpresion);

            var member   = GetExpressionPropertyOrThrow <TProperty>(propertyExpresion);
            var property = GetInterfacePropertyOrThrow <TInterface>(member);

            var variableProperty = target.Properties.FirstOrDefault(prop => prop.DefinitionName == property.Name);

            if (variableProperty != null)
            {
                // The descriptor associated with the property will do the conversion already if supported.
                variableProperty.Value = value;
            }
            else
            {
                var elementProperty = TypeDescriptor.GetProperties(target).Find(property.Name, false);
                if (elementProperty == null)
                {
                    throw new NotSupportedException(string.Format(
                                                        CultureInfo.CurrentCulture,
                                                        Resources.ToolkitInterfaceLayer_InstancePropertyNotFound,
                                                        target.GetType().Name,
                                                        property.Name));
                }

                // We don't do type conversion from element (reflection) properties as they will already be typed accesses.
                elementProperty.SetValue(target, value);
            }
        }
        internal static TProperty GetValue <TInterface, TProperty>(IProductElement target, Expression <Func <TProperty> > propertyExpresion)
        {
            Guard.NotNull(() => target, target);
            Guard.NotNull(() => propertyExpresion, propertyExpresion);

            var member   = GetExpressionPropertyOrThrow <TProperty>(propertyExpresion);
            var property = GetInterfacePropertyOrThrow <TInterface>(member);

            var variableProperty = target.Properties.FirstOrDefault(prop => prop.DefinitionName == property.Name);

            if (variableProperty != null)
            {
                var value = variableProperty.Value;
                if (value != null && !typeof(TProperty).IsAssignableFrom(value.GetType()))
                {
                    return((TProperty)property.Converter.ConvertFrom(value));
                }

                return((TProperty)value);
            }

            var elementProperty = TypeDescriptor.GetProperties(target).Find(property.Name, false);

            if (elementProperty == null)
            {
                throw new NotSupportedException(string.Format(
                                                    CultureInfo.CurrentCulture,
                                                    Resources.ToolkitInterfaceLayer_InstancePropertyNotFound,
                                                    target.GetType().Name,
                                                    property.Name));
            }

            // We don't do type conversion from element (reflection) properties as they will already be typed accesses.
            return((TProperty)elementProperty.GetValue(target));
        }
 private static Func <IProductElement, ISolutionBuilderContext, ProductElementViewModel> FindFactory(IProductElement element)
 {
     return(vmFactories.Where(f => f.Key.IsAssignableFrom(element.GetType())).Select(f => f.Value).First());
 }