Exemple #1
0
        /// <summary>
        ///     Sets all members of the given member.
        /// </summary>
        /// <typeparam name="T">The type to create an instance of.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <param name="memberInformation">The current member.</param>
        private static void SetAllMembers <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation) where T : class
        {
            // Check if children should be set or not
            if (!IncludeChildMembers(options, memberInformation))
            {
                return;
            }

            // Get the properties of the current member as member information
            var propertyInfos = memberInformation.MemberType.GetPublicSettableProperties()
                                .GetMemberInformation(memberInformation);

            propertyInfos.ForEach(x =>
            {
                // Check if member should be set or not
                if (!IncludeMember(options, x))
                {
                    return;
                }

                // Create member value
                var value = GetValue(options, x);
                x.PropertyInfo.SetValue(memberInformation.MemberObject, value, null);

                // Set children of value (recursive call)
                var currentMember = x as MemberInformation;
                if (currentMember != null)
                {
                    currentMember.MemberObject = value;
                }

                SetAllMembers(options, currentMember);
            });
        }
Exemple #2
0
        /// <summary>
        ///     Tries to create an array value for the given type.
        /// </summary>
        /// <typeparam name="T">The type of the instance to create.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <param name="memberInformation">The member to check.</param>
        /// <returns>Returns the created value, or null if the given type is not an array type.</returns>
        private static Object TryCreateArrayValue <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation) where T : class
        {
            // Check if member is an array type
            if (!memberInformation.MemberType.IsArray)
            {
                return(null);
            }

            // Create the array
            var elementType = memberInformation.MemberType.GetElementType();
            var array       = Array.CreateInstance(elementType, GetCollectionItemCount(options));

            // Add items
            var anonymousItemName = GetAnonymousItemName(options);

            for (var i = 0; i < array.Length; i++)
            {
                var currentMember = new MemberInformation
                {
                    MemberType = elementType,
                    MemberPath = $"{memberInformation.MemberPath}.{anonymousItemName}",
                    MemberName = anonymousItemName
                };

                // Get the value of the current array item.
                var arrayItemValue = GetValue(options, currentMember);
                currentMember.MemberObject = arrayItemValue;
                SetAllMembers(options, currentMember);
                array.SetValue(arrayItemValue, i);
            }

            return(array);
        }
Exemple #3
0
        /// <summary>
        ///     Gets the matching factory for the given member.
        /// </summary>
        /// <exception cref="CreateInstanceException">Multiple matching factories found.</exception>
        /// <typeparam name="T">The type of the instance to create.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <param name="memberInformation">The member to check.</param>
        /// <returns>Returns the matching factory, or null if no factory was found.</returns>
        private static IInstanceFactory GetFactory <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation) where T : class
        {
            // Get matching factory
            var factory = GetExactlymatchingFactory(options, memberInformation);

            if (factory != null)
            {
                return(factory);
            }

            // Try get inner type of null-able
            var nullableType = memberInformation.MemberType.GetTypeFromNullable();

            if (nullableType == null)
            {
                return(null);
            }

            // Update type
            if (memberInformation is MemberInformation info)
            {
                info.MemberType = nullableType;
            }

            return(GetExactlymatchingFactory(options, memberInformation));
        }
Exemple #4
0
        /// <summary>
        ///     Populates the given instance if it is a collection, based on the collection configuration.
        /// </summary>
        /// <typeparam name="T">The type of the instance to create.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <param name="memberInformation">The member to check.</param>
        /// <param name="collectionInstance">The instance to populate.</param>
        /// <returns>Returns the populated or unmodified instance.</returns>
        private static Object TryPopulateCollection <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation, Object collectionInstance) where T : class
        {
            // Check if collection should get populated or not
            if (!PopulateCollection(options) || collectionInstance == null)
            {
                return(collectionInstance);
            }

            // Check if type is collection type
            if (!memberInformation.MemberType.ImplementsICollectionT())
            {
                return(collectionInstance);
            }

            // Get generic parameter type
            var genericArgumentTypes = memberInformation
                                       .MemberType
                                       .GetGenericTypeArguments()
                                       .ToArray();

            // Get the add method

            var addMethod = memberInformation.MemberType
                            .GetRuntimeMethod("Add", genericArgumentTypes);

            // Add items
            var anonymousItemName = GetAnonymousItemName(options);
            var collectionCount   = GetCollectionItemCount(options);

            for (var i = 0; i < collectionCount; i++)
            {
                var addParameters = new List <Object>();
                genericArgumentTypes
                .ForEach(x =>
                {
                    var currentMember = new MemberInformation
                    {
                        MemberType = x,
                        MemberPath = $"{memberInformation.MemberPath}.{anonymousItemName}",
                        MemberName = anonymousItemName
                    };

                    // Get the value for the current collection item.
                    var collectionItemValue    = GetValue(options, currentMember);
                    currentMember.MemberObject = collectionItemValue;
                    SetAllMembers(options, currentMember);

                    addParameters.Add(collectionItemValue);
                });

                addMethod.Invoke(collectionInstance, addParameters.ToArray());
            }

            return(collectionInstance);
        }
Exemple #5
0
        /// <summary>
        ///     Gets the number of items to create for a collection.
        /// </summary>
        /// <typeparam name="T">The type of the instance to create.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <returns>Returns the number of items to create.</returns>
        private static Int32 GetCollectionItemCount <T>(ICreateInstanceOptionsComplete <T> options) where T : class
        {
            //Return count of 0 if collection should net get populated
            if (!PopulateCollection(options))
            {
                return(0);
            }

            var min = options.PopulateCollectionsMinCount ?? PopulateCollectionsMinCount;
            var max = options.PopulateCollectionsMaxCount ?? PopulateCollectionsMaxCount;

            return(RandomValueEx.GetRandomInt32(min, max));
        }
Exemple #6
0
        /// <summary>
        ///     Gets a value for the given member.
        /// </summary>
        /// <exception cref="CreateInstanceException">Value creation failed.</exception>
        /// <typeparam name="T">The type of the instance to create.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <param name="memberInformation">The member to check.</param>
        /// <returns>Returns the created value.</returns>
        private static Object GetValue <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation) where T : class
        {
            // Try get value from factory
            var factory = GetFactory(options, memberInformation);

            if (factory != null)
            {
                try
                {
                    return(factory.CreateValue(memberInformation));
                }
                catch (Exception ex)
                {
                    throw new CreateInstanceException("Factory has thrown exception.", ex, factory.ToString(), null, memberInformation);
                }
            }

            // Try create array value
            var value = TryCreateArrayValue(options, memberInformation);

            if (value != null)
            {
                return(value);
            }

            // Create value (first try IEnumerable than anything else)
            value = TryCreateCollectionValue(memberInformation);
            // ReSharper disable once InvertIf
            if (value == null)
            {
                try
                {
                    value = CreateValueUsingAcrivator(memberInformation);
                }
                catch (Exception ex)
                {
                    throw new CreateInstanceException($"Failed to create instance due to missing or invalid factory for type '{memberInformation.MemberType}'.",
                                                      ex,
                                                      null,
                                                      null,
                                                      memberInformation);
                }
            }

            // Populate collection if collection (could be ICollection)
            return(TryPopulateCollection(options, memberInformation, value));
        }
Exemple #7
0
 /// <summary>
 ///     Creates the root instance.
 /// </summary>
 /// <exception cref="CreateInstanceException">Value creation failed.</exception>
 /// <typeparam name="T">The type of the instance to create.</typeparam>
 /// <param name="options">Some create instance options.</param>
 /// <param name="memberInformation">The member to create.</param>
 /// <returns>Returns the created value.</returns>
 private static T CreateRootMember <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation) where T : class
 {
     try
     {
         var value = GetValue(options, memberInformation);
         return((T)value);
     }
     catch (Exception ex)
     {
         throw new CreateInstanceException($"Failed to create root object of type: {typeof(T).Name}.",
                                           ex,
                                           options.Factories.Concat(DefaultFactories)
                                           .StringJoin(Environment.NewLine),
                                           null,
                                           memberInformation);
     }
 }
Exemple #8
0
        /// <summary>
        ///     Gets the matching factory for the given member.
        /// </summary>
        /// <exception cref="CreateInstanceException">Multiple matching factories found.</exception>
        /// <typeparam name="T">The type of the instance to create.</typeparam>
        /// <param name="options">Some create instance options.</param>
        /// <param name="memberInformation">The member to check.</param>
        /// <returns>Returns the matching factory, or null if no factory was found.</returns>
        private static IInstanceFactory GetExactlymatchingFactory <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation) where T : class
        {
            // Get factory from options
            var matchingFactories = options.Factories.Where(x => RuleInspector.Inspect(x.SelectionRules, memberInformation) == MemberSelectionResult.IncludeMember)
                                    .ToList();

            if (matchingFactories.Count == 1)
            {
                return(matchingFactories.Single());
            }

            // Check if multiple factories have matched
            if (matchingFactories.Any())
            {
                throw new CreateInstanceException(
                          $"Found multiple matching factories for member (in options). Type is '{memberInformation.MemberType}'. Please make sure only one factory matches the member.",
                          null,
                          options.Factories.StringJoin(Environment.NewLine),
                          null,
                          memberInformation);
            }

            // Get factory from default factories
            matchingFactories = DefaultFactories.Where(x => RuleInspector.Inspect(x.SelectionRules, memberInformation) == MemberSelectionResult.IncludeMember)
                                .ToList();
            if (matchingFactories.Count == 1)
            {
                return(matchingFactories.Single());
            }

            //Check if multiple factories have matched
            if (matchingFactories.Any())
            {
                throw new CreateInstanceException(
                          $"Found multiple matching factories for member (in global configuration). Type is '{memberInformation.MemberType}'.  Please make sure only one factory matches the member.",
                          null,
                          DefaultFactories.StringJoin(Environment.NewLine),
                          null,
                          memberInformation);
            }

            // No factory found
            return(null);
        }
Exemple #9
0
        public static T CreateInstance <T>([NotNull] this ICreateInstanceOptionsComplete <T> options) where T : class
        {
            options.ThrowIfNull(nameof(options));

            //Create instance
            var rootMemberInformation = new MemberInformation
            {
                MemberType = typeof(T),
                MemberPath = String.Empty,
                MemberName = String.Empty
            };
            var instance = CreateRootMember(options, rootMemberInformation);

            rootMemberInformation.MemberObject = instance;

            //Set each member of the created instance.
            SetAllMembers(options, rootMemberInformation);

            return(instance);
        }
Exemple #10
0
 /// <summary>
 ///     Gets the name for anonymous items.
 /// </summary>
 /// <typeparam name="T">The type of the instance to create.</typeparam>
 /// <param name="options">Some create instance options.</param>
 /// <returns>Returns the name to use.</returns>
 private static String GetAnonymousItemName <T>(ICreateInstanceOptionsComplete <T> options) where T : class
 => options.AnonymousItemName ?? AnonymousItemName;
Exemple #11
0
 /// <summary>
 ///     Gets a value determining whether collections should get populated or not.
 /// </summary>
 /// <typeparam name="T">The type of the instance to create.</typeparam>
 /// <param name="options">Some create instance options.</param>
 /// <returns>Returns a value of true if collections should get populated or not.</returns>
 private static Boolean PopulateCollection <T>(ICreateInstanceOptionsComplete <T> options) where T : class
 => options.PopulateCollections ?? PopulateCollections;
Exemple #12
0
 /// <summary>
 ///     Gets a value determining whether the children should be included or not.
 /// </summary>
 /// <exception cref="CreateInstanceException">No matching rule was found.</exception>
 /// <typeparam name="T">The type of the instance to create.</typeparam>
 /// <param name="options">Some create instance options.</param>
 /// <param name="memberInformation">The member to check.</param>
 /// <returns>Returns a value of true if the children should be included; otherwise, false.</returns>
 private static Boolean IncludeChildMembers <T>(ICreateInstanceOptionsComplete <T> options, IMemberInformation memberInformation)
 => ShouldMemberBeIncluded(memberInformation, options.MemberChildrenSelectionRules, DefaultMemberChildreSelectionRules);