/// <summary>
        /// This will return an ExtendableCompilableTypeConverterFactory based around the destination types having a zero parameter constructor and
        /// its data being set through public properties
        /// </summary>
        public static ExtendableCompilableTypeConverterFactory GeneratePropertySetterBasedFactory(
            INameMatcher nameMatcher,
            CompilableTypeConverterByPropertySettingFactory.PropertySettingTypeOptions propertySettingTypeOptions,
            IEnumerable <ICompilablePropertyGetterFactory> basePropertyGetterFactories,
            IEnumerable <PropertyInfo> propertiesToIgnore,
            ByPropertySettingNullSourceBehaviourOptions nullSourceBehaviour,
            IEnumerable <PropertyInfo> initialisedFlagsIfTranslatingNullsToEmptyInstances,
            EnumerableSetNullHandlingOptions enumerableSetNullHandling)
        {
            if (nameMatcher == null)
            {
                throw new ArgumentNullException("nameMatcher");
            }
            if (!Enum.IsDefined(typeof(CompilableTypeConverterByPropertySettingFactory.PropertySettingTypeOptions), propertySettingTypeOptions))
            {
                throw new ArgumentOutOfRangeException("propertySettingTypeOptions");
            }
            if (basePropertyGetterFactories == null)
            {
                throw new ArgumentNullException("basePropertyGetterFactories");
            }
            if (propertiesToIgnore == null)
            {
                throw new ArgumentNullException("propertiesToIgnore");
            }
            if (initialisedFlagsIfTranslatingNullsToEmptyInstances == null)
            {
                throw new ArgumentNullException("initialisedFlagsIfTranslatingNullsToEmptyInstances");
            }
            if (!Enum.IsDefined(typeof(ByPropertySettingNullSourceBehaviourOptions), nullSourceBehaviour))
            {
                throw new ArgumentOutOfRangeException("nullSourceBehaviour");
            }
            if (!Enum.IsDefined(typeof(EnumerableSetNullHandlingOptions), enumerableSetNullHandling))
            {
                throw new ArgumentOutOfRangeException("enumerableSetNullHandling");
            }

            return(new ExtendableCompilableTypeConverterFactory(
                       nameMatcher,
                       basePropertyGetterFactories,
                       propertyGetterFactories => new CompilableTypeConverterByPropertySettingFactory(
                           // Define a ConverterFactoryGenerator to return a CompilableTypeConverterByPropertySettingFactory when new conversions are registered
                           new CombinedCompilablePropertyGetterFactory(propertyGetterFactories),
                           propertySettingTypeOptions,
                           propertiesToIgnore,
                           nullSourceBehaviour,
                           initialisedFlagsIfTranslatingNullsToEmptyInstances
                           ),
                       new CompilableTypeConverterPropertyGetterFactoryExtrapolator(
                           nameMatcher,
                           enumerableSetNullHandling
                           )
                       ));
        }
            public CompilableTypeConverterPropertyGetterFactoryExtrapolator(INameMatcher nameMatcher, EnumerableSetNullHandlingOptions enumerableSetNullHandling)
            {
                if (nameMatcher == null)
                {
                    throw new ArgumentNullException("nameMatcher");
                }
                if (!Enum.IsDefined(typeof(EnumerableSetNullHandlingOptions), enumerableSetNullHandling))
                {
                    throw new ArgumentOutOfRangeException("enumerableSetNullHandling");
                }

                _nameMatcher = nameMatcher;
                _enumerableSetNullHandling = enumerableSetNullHandling;
            }
        public ConverterWrapper(ByPropertySettingNullSourceBehaviourOptions nullSourceBehaviour, EnumerableSetNullHandlingOptions enumerableSetNullHandling)
        {
            if (!Enum.IsDefined(typeof(ByPropertySettingNullSourceBehaviourOptions), nullSourceBehaviour))
            {
                throw new ArgumentOutOfRangeException("nullSourceBehaviour");
            }
            if (!Enum.IsDefined(typeof(EnumerableSetNullHandlingOptions), enumerableSetNullHandling))
            {
                throw new ArgumentOutOfRangeException("enumerableSetNullHandling");
            }

            _nullSourceBehaviour       = nullSourceBehaviour;
            _enumerableSetNullHandling = enumerableSetNullHandling;
            _allPropertiesToIgnoreToPropertySetterConversions      = new List <PropertyInfo>();
            _allInitialisedFlagsIfTranslatingNullsToEmptyInstances = new List <PropertyInfo>();
            _converterCache = new Dictionary <Tuple <Type, Type>, object>();

            // Prepare converter factories (for by-constructor and by-property-setters) using the base types (AssignableType and
            // EnumConversion property getter factories)
            var nameMatcher = new CaseInsensitiveSkipUnderscoreNameMatcher();
            var basePropertyGetterFactories = new ICompilablePropertyGetterFactory[]
            {
                new CompilableAssignableTypesPropertyGetterFactory(nameMatcher),
                new CompilableEnumConversionPropertyGetterFactory(nameMatcher)
            };

            _constructorBasedConverterFactory = ExtendableCompilableTypeConverterFactoryHelpers.GenerateConstructorBasedFactory(
                nameMatcher,
                new ArgsLengthTypeConverterPrioritiserFactory(),
                basePropertyGetterFactories,
                _enumerableSetNullHandling
                );
            _propertySetterBasedConverterFactory = ExtendableCompilableTypeConverterFactoryHelpers.GeneratePropertySetterBasedFactory(
                nameMatcher,
                CompilableTypeConverterByPropertySettingFactory.PropertySettingTypeOptions.MatchAll,
                basePropertyGetterFactories,
                _allPropertiesToIgnoreToPropertySetterConversions,
                _nullSourceBehaviour,
                _allInitialisedFlagsIfTranslatingNullsToEmptyInstances,
                _enumerableSetNullHandling
                );
        }
Example #4
0
        public EnumerableCompilablePropertyGetterFactory(
            INameMatcher nameMatcher,
            ICompilableTypeConverter <TPropertyOnSourceElement, TPropertyAsRetrievedElement> typeConverter,
            EnumerableSetNullHandlingOptions enumerableSetNullHandling)
        {
            if (nameMatcher == null)
            {
                throw new ArgumentNullException("nameMatcher");
            }
            if (typeConverter == null)
            {
                throw new ArgumentNullException("typeConverter");
            }
            if (!Enum.IsDefined(typeof(EnumerableSetNullHandlingOptions), enumerableSetNullHandling))
            {
                throw new ArgumentOutOfRangeException("enumerableSetNullHandling");
            }

            _nameMatcher               = nameMatcher;
            _typeConverter             = typeConverter;
            _enumerableSetNullHandling = enumerableSetNullHandling;
        }
        /// <summary>
        /// This will return an ExtendableCompilableTypeConverterFactory that is based around the destination types being instantiated by constructor. Note
        /// that this method has less options than GeneratePropertySetterBasedFactory since by-property-setter translation may be used in more scenarios
        /// that the by-constructor translations and with more specific configurations (eg. by-constructor translations can't be used in Entity Framework
        /// IQueryable mappings since constructors with parameters can not be used - the nullSourceBehaviour and enumerableSetNullHandling options are
        /// to tailor conversions to work with such IQueryable translations).
        /// </summary>
        public static ExtendableCompilableTypeConverterFactory GenerateConstructorBasedFactory(
            INameMatcher nameMatcher,
            ITypeConverterPrioritiserFactory converterPrioritiser,
            IEnumerable <ICompilablePropertyGetterFactory> basePropertyGetterFactories,
            EnumerableSetNullHandlingOptions enumerableSetNullHandling)
        {
            if (nameMatcher == null)
            {
                throw new ArgumentNullException("nameMatcher");
            }
            if (converterPrioritiser == null)
            {
                throw new ArgumentNullException("converterPrioritiser");
            }
            if (basePropertyGetterFactories == null)
            {
                throw new ArgumentNullException("basePropertyGetterFactories");
            }
            if (!Enum.IsDefined(typeof(EnumerableSetNullHandlingOptions), enumerableSetNullHandling))
            {
                throw new ArgumentOutOfRangeException("enumerableSetNullHandling");
            }

            return(new ExtendableCompilableTypeConverterFactory(
                       nameMatcher,
                       basePropertyGetterFactories,
                       propertyGetterFactories => new CompilableTypeConverterByConstructorFactory(
                           // Define a ConverterFactoryGenerator to return a CompilableTypeConverterByConstructorFactory when new conversions are registered
                           converterPrioritiser,
                           new CombinedCompilablePropertyGetterFactory(propertyGetterFactories),
                           ParameterLessConstructorBehaviourOptions.Ignore
                           ),
                       new CompilableTypeConverterPropertyGetterFactoryExtrapolator(
                           nameMatcher,
                           enumerableSetNullHandling
                           )
                       ));
        }
        public EnumerableCompilablePropertyGetter(
            PropertyInfo propertyInfo,
            ICompilableTypeConverter <TPropertyOnSourceElement, TPropertyAsRetrievedElement> typeConverter,
            EnumerableSetNullHandlingOptions enumerableSetNullHandling)
        {
            // When checking types here, we're effectively only allowing equality - not IsAssignableFrom - of the elements of the IEnumerable data (since IEnumerable<B>
            // is not assignable to IEnumerable<A> even if B is derived from / implements A), this is desirable to ensure that the most appropriate property getter
            // ends up getting matched
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }
            if (!typeof(TSourceObject).HasProperty(propertyInfo))
            {
                throw new ArgumentException("Invalid propertyInfo, not available on type TSource");
            }
            if (!typeof(IEnumerable <TPropertyOnSourceElement>).IsAssignableFrom(propertyInfo.PropertyType))
            {
                throw new ArgumentException("Invalid propertyInfo - its PropertyType must be assignable match to IEnumerable<TPropertyOnSourceElement>");
            }
            if (!typeof(IEnumerable <TPropertyAsRetrievedElement>).IsAssignableFrom(typeof(TPropertyAsRetrieved)))
            {
                throw new ArgumentException("Invalid configuration - TPropertyAsRetrieved must be assignable to IEnumerable<TPropertyAsRetrievedElement>");
            }
            if (typeConverter == null)
            {
                throw new ArgumentNullException("typeConverter");
            }
            if (!Enum.IsDefined(typeof(EnumerableSetNullHandlingOptions), enumerableSetNullHandling))
            {
                throw new ArgumentOutOfRangeException("enumerableSetNullHandling");
            }

            _propertyInfo             = propertyInfo;
            _typeConverter            = typeConverter;
            EnumerableSetNullHandling = enumerableSetNullHandling;
        }