public static void TestPropertySetting()
        {
            // Prepare a converter factory using the base types (AssignableType and EnumConversion property getter factories)
            var nameMatcher      = new CaseInsensitiveSkipUnderscoreNameMatcher();
            var converterFactory = ExtendableCompilableTypeConverterFactoryHelpers.GeneratePropertySetterBasedFactory(
                nameMatcher,
                CompilableTypeConverterByPropertySettingFactory.PropertySettingTypeOptions.MatchAsManyAsPossible,
                new ICompilablePropertyGetterFactory[]
            {
                new CompilableAssignableTypesPropertyGetterFactory(nameMatcher),
                new CompilableEnumConversionPropertyGetterFactory(nameMatcher)
            },
                new PropertyInfo[0],                 // propertiesToIgnore
                ByPropertySettingNullSourceBehaviourOptions.UseDestDefaultIfSourceIsNull,
                new PropertyInfo[0],                 // initialisedFlagsIfTranslatingNullsToEmptyInstances (not applicable with UseDestDefaultIfSourceIsNull)
                EnumerableSetNullHandlingOptions.ReturnNullSetForNullInput
                );

            // Extend the converter to handle SourceType.Sub1 to ConstructorDestType.Sub1 and IEnumerable<SourceType.Sub1> to IEnumerable<ConstructorDestType.Sub1>
            // - This will raise an exception if unable to create the mapping
            converterFactory = converterFactory.CreateMap <SourceType.Sub1, StandardDestType.Sub1>();

            // This will enable the creation of a converter for SourceType to ConstructorDestType
            // - This will throw an exception if unable to generate an appropriate converter
            var converter = converterFactory.Get <SourceType, StandardDestType>();

            var result = converter.Convert(getExampleSourceType());
        }
        public static void TestConstructor()
        {
            // Prepare a converter factory using the base types (AssignableType and EnumConversion property getter factories)
            var nameMatcher      = new CaseInsensitiveSkipUnderscoreNameMatcher();
            var converterFactory = ExtendableCompilableTypeConverterFactoryHelpers.GenerateConstructorBasedFactory(
                nameMatcher,
                new ArgsLengthTypeConverterPrioritiserFactory(),
                new ICompilablePropertyGetterFactory[]
            {
                new CompilableAssignableTypesPropertyGetterFactory(nameMatcher),
                new CompilableEnumConversionPropertyGetterFactory(nameMatcher)
            },
                EnumerableSetNullHandlingOptions.ReturnNullSetForNullInput
                );

            // Extend the converter to handle SourceType.Sub1 to ConstructorDestType.Sub1 and IEnumerable<SourceType.Sub1> to IEnumerable<ConstructorDestType.Sub1>
            // - This will raise an exception if unable to create the mapping
            converterFactory = converterFactory.CreateMap <SourceType.Sub1, ConstructorDestType.Sub1>();

            // This will enable the creation of a converter for SourceType to ConstructorDestType
            // - This will throw an exception if unable to generate an appropriate converter
            var converter = converterFactory.Get <SourceType, ConstructorDestType>();

            var result = converter.Convert(getExampleSourceType());
        }
        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
                );
        }
        public void VariousUsingExtendableCompilableTypeConverterFactoryHelpers()
        {
            var nameMatcher      = new CaseInsensitiveSkipUnderscoreNameMatcher();
            var converterFactory =
                ExtendableCompilableTypeConverterFactoryHelpers.GenerateConstructorBasedFactory(
                    nameMatcher,
                    new ArgsLengthTypeConverterPrioritiserFactory(),
                    new ICompilablePropertyGetterFactory[]
            {
                new CompilableAssignableTypesPropertyGetterFactory(nameMatcher),
                new CompilableEnumConversionPropertyGetterFactory(nameMatcher)
            },
                    EnumerableSetNullHandlingOptions.ReturnNullSetForNullInput
                    )
                .CreateMap <SourceType.Sub1, ConstructorDestType.Sub1>()
                .CreateMap <SourceType, ConstructorDestType>();
            var converter = converterFactory.Get <SourceType, ConstructorDestType>();

            var source = new SourceType
            {
                Value = new SourceType.Sub1 {
                    Name = "Test1"
                },
                ValueList = new[]
                {
                    new SourceType.Sub1 {
                        Name = "Test2"
                    },
                    new SourceType.Sub1 {
                        Name = "Test3"
                    }
                },
                ValueEnum = SourceType.Sub2.EnumValue2
            };
            var dest = converter.Convert(source);

            Assert.AreEqual("Test1", dest.Value.Name);
            Assert.AreEqual(2, dest.ValueList.Count());
            Assert.AreEqual("Test2", dest.ValueList.ElementAt(0).Name);
            Assert.AreEqual("Test3", dest.ValueList.ElementAt(1).Name);
            Assert.AreEqual(ConstructorDestType.Sub2.EnumValue2, dest.ValueEnum);
        }