Exemple #1
0
        private void PrepareCreate(AutoGenerateContext context)
        {
            // Check a create handler hasn't previously been set or configured externally
            if (!CreateInitialized && CreateActions[currentRuleSet] == null)
            {
                CreateActions[currentRuleSet] = faker =>
                {
                    // Only auto create if the 'default' rule set is defined for generation
                    // This is because any specific rule sets are expected to handle the full creation
                    if (context.RuleSets.Contains(currentRuleSet))
                    {
                        // Set the current type being generated
                        context.GenerateType = typeof(TType);
                        context.GenerateName = null;

                        // Get the type generator
                        var generator = AutoGeneratorFactory.GetGenerator(context);
                        return((TType)generator.Generate(context));
                    }

                    return(DefaultCreateAction.Invoke(faker));
                };

                CreateInitialized = true;
            }
        }
Exemple #2
0
        private void PrepareFinish(AutoGenerateContext context)
        {
            if (!FinishInitialized)
            {
                // Try and get the registered finish with for the current rule
                FinalizeActions.TryGetValue(currentRuleSet, out FinalizeAction <TType> finishWith);

                // Add an internal finish to auto populate any remaining values
                FinishWith((faker, instance) =>
                {
                    // Extract the unpopulated member infos
                    var members     = new List <MemberInfo>();
                    var memberNames = GetRuleSetsMemberNames(context);

                    foreach (var member in TypeProperties)
                    {
                        if (!memberNames.Contains(member.Key))
                        {
                            members.Add(member.Value);
                        }
                    }

                    // Finalize the instance population
                    context.Binder.PopulateInstance <TType>(instance, context, members);

                    // Ensure the default finish with is invoke
                    if (finishWith != null)
                    {
                        finishWith.Action(faker, instance);
                    }
                });

                FinishInitialized = true;
            }
        }
Exemple #3
0
        private void PrepareFinish(AutoGenerateContext context)
        {
            if (!FinishInitialized)
            {
                // Try and get the registered finish with for the current rule
                FinalizeActions.TryGetValue(currentRuleSet, out FinalizeAction <TType> finishWith);

                // Add an internal finish to auto populate any remaining values
                FinishWith((faker, instance) =>
                {
#if !NETSTANDARD1_3
                    // If dynamic objects are supported, populate as a dictionary
                    var type = instance?.GetType();

                    if (ReflectionHelper.IsExpandoObject(type))
                    {
                        // Configure the context
                        context.ParentType   = null;
                        context.GenerateType = type;
                        context.GenerateName = null;

                        context.Instance = instance;

                        // Get the expando generator and populate the instance
                        var generator = AutoGeneratorFactory.GetGenerator(context);
                        generator.Generate(context);

                        // Clear the context instance
                        context.Instance = null;

                        return;
                    }
#endif
                    // Otherwise continue with a standard populate
                    // Extract the unpopulated member infos
                    var members     = new List <MemberInfo>();
                    var memberNames = GetRuleSetsMemberNames(context);

                    foreach (var member in TypeProperties)
                    {
                        if (!memberNames.Contains(member.Key))
                        {
                            members.Add(member.Value);
                        }
                    }

                    // Finalize the instance population
                    context.Binder.PopulateInstance <TType>(instance, context, members);

                    // Ensure the default finish with is invoke
                    if (finishWith != null)
                    {
                        finishWith.Action(faker, instance);
                    }
                });

                FinishInitialized = true;
            }
        }
        internal AutoGenerateOverrideContext(AutoGenerateContext generateContext)
        {
            GenerateContext = generateContext;

            GenerateType = GenerateContext.GenerateType;
            GenerateName = GenerateContext.GenerateName;
            Faker        = GenerateContext.Faker;
            RuleSets     = GenerateContext.RuleSets;
        }
        /// <summary>
        /// Generates an instance of type <typeparamref name="TType"/>.
        /// </summary>
        /// <typeparam name="TType">The instance type to generate.</typeparam>
        /// <param name="context">The <see cref="AutoGenerateContext"/> instance for the current generate request.</param>
        /// <returns>The generated instance.</returns>
        public static TType Generate <TType>(this AutoGenerateContext context)
        {
            if (context != null)
            {
                // Set the generate type for the current request
                context.GenerateType = typeof(TType);

                // Get the type generator and return a value
                var generator = AutoGeneratorFactory.GetGenerator(context);
                return((TType)generator.Generate(context));
            }

            return(default);
        private static IAutoGenerator ResolveGenerator(AutoGenerateContext context)
        {
            // Do some type -> generator mapping
            var type = context.GenerateType;

            if (type.IsArray)
            {
                type = type.GetElementType();
                return(CreateGenericGenerator(typeof(ArrayGenerator <>), type));
            }

            if (ReflectionHelper.IsEnum(type))
            {
                return(CreateGenericGenerator(typeof(EnumGenerator <>), type));
            }

            if (ReflectionHelper.IsGenericType(type))
            {
                // For generic types we need to interrogate the inner types
                var definition = type.GetGenericTypeDefinition();
                var generics   = ReflectionHelper.GetGenericArguments(type);

                if (IsDictionaryDefinition(definition))
                {
                    var keyType   = generics.ElementAt(0);
                    var valueType = generics.ElementAt(1);

                    return(CreateGenericGenerator(typeof(DictionaryGenerator <,>), keyType, valueType));
                }

                if (IsEnumerableDefinition(definition))
                {
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(EnumerableGenerator <>), type));
                }

                if (IsNullableDefinition(definition))
                {
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(NullableGenerator <>), type));
                }
            }

            // Resolve the generator from the type
            if (Generators.ContainsKey(type))
            {
                return(Generators[type]);
            }

            return(CreateGenericGenerator(typeof(TypeGenerator <>), type));
        }
Exemple #7
0
        internal static IAutoGenerator GetGenerator(AutoGenerateContext context)
        {
            var generator = ResolveGenerator(context);

            // Check if any overrides are available for this generate request
            var overrides = context.Overrides.Where(o => o.CanOverride(context)).ToList();

            if (overrides.Any())
            {
                return(new AutoGeneratorOverrideInvoker(generator, overrides));
            }

            return(generator);
        }
Exemple #8
0
        private IEnumerable <string> GetRuleSetsMemberNames(AutoGenerateContext context)
        {
            // Get the member names from all the rule sets being used to generate the instance
            var members = new List <string>();

            foreach (var ruleSetName in context.RuleSets)
            {
                if (Actions.TryGetValue(ruleSetName, out var ruleSet))
                {
                    members.AddRange(ruleSet.Keys);
                }
            }

            return(members);
        }
Exemple #9
0
        object IAutoGenerator.Generate(AutoGenerateContext context)
        {
            // Create the override context and generate an initial instance
            var overrideContext = new AutoGenerateOverrideContext(context)
            {
                Instance = Generator.Generate(context)
            };

            // Then allow each override to alter the intial instance
            foreach (var generatorOverride in Overrides)
            {
                generatorOverride.Generate(overrideContext);
            }

            return(overrideContext.Instance);
        }
Exemple #10
0
        /// <summary>
        /// Creates an instance of <typeparamref name="TType"/>.
        /// </summary>
        /// <typeparam name="TType">The type of instance to create.</typeparam>
        /// <param name="context">The <see cref="AutoGenerateContext"/> instance for the generate request.</param>
        /// <returns>The created instance of <typeparamref name="TType"/>.</returns>
        public virtual TType CreateInstance <TType>(AutoGenerateContext context)
        {
            var constructor = GetConstructor <TType>();

            if (constructor != null)
            {
                // If a constructor is found generate values for each of the parameters
                var parameters = (from p in constructor.GetParameters()
                                  let g = AutoGeneratorFactory.GetGenerator(p.ParameterType, context)
                                          select g.Generate(context)).ToArray();

                return((TType)constructor.Invoke(parameters));
            }

            return(default(TType));
        }
Exemple #11
0
        private void PrepareCreate(AutoGenerateContext context)
        {
            // Check a create handler hasn't previously been set or configured externally
            if (!CreateInitialized && CreateActions[currentRuleSet] == null)
            {
                CreateActions[currentRuleSet] = faker =>
                {
                    // Only auto create if the 'default' rule set is defined for generation
                    // This is because any specific rule sets are expected to handle the full creation
                    if (context.RuleSets.Contains(currentRuleSet))
                    {
                        var type = typeof(TType);

                        // Set the current type being generated
                        context.ParentType   = null;
                        context.GenerateType = type;
                        context.GenerateName = null;

                        // Get the members that should not be set during construction
                        var memberNames = GetRuleSetsMemberNames(context);

                        foreach (var memberName in TypeProperties.Keys)
                        {
                            if (memberNames.Contains(memberName))
                            {
                                var path     = $"{type.FullName}.{memberName}";
                                var existing = context.Config.SkipPaths.Any(s => s == path);

                                if (!existing)
                                {
                                    context.Config.SkipPaths.Add(path);
                                }
                            }
                        }

                        // Create a blank instance. It will be populated in the FinalizeAction registered
                        // by PrepareFinish (context.Binder.PopulateInstance<TType>).
                        return(context.Binder.CreateInstance <TType>(context));
                    }

                    return(DefaultCreateAction.Invoke(faker));
                };

                CreateInitialized = true;
            }
        }
Exemple #12
0
        /// <summary>
        /// Populates the provided instance with auto generated values.
        /// </summary>
        /// <typeparam name="TType">The type of instance to populate.</typeparam>
        /// <param name="instance">The instance to populate.</param>
        /// <param name="context">The <see cref="AutoGenerateContext"/> instance for the generate request.</param>
        /// <param name="members">An optional collection of members to populate. If null, all writable instance members are populated.</param>
        /// <remarks>
        /// Due to the boxing nature of value types, the <paramref name="instance"/> parameter is an object. This means the populated
        /// values are applied to the provided instance and not a copy.
        /// </remarks>
        public virtual void PopulateInstance <TType>(object instance, AutoGenerateContext context, IEnumerable <MemberInfo> members = null)
        {
            var type = typeof(TType);

            // We can only populate non-null instances
            // Dictionaries and Enumerables are populated via their constructors
            if (instance == null || IsDictionary(type) || IsEnumerable(type))
            {
                return;
            }

            // If no members are provided, get all value candidates for the instance
            if (members == null)
            {
                members = (from m in GetMembers(type)
                           select m.Value);
            }

            // Iterate the members and bind a generated value
            foreach (var member in members)
            {
                // We may be resolving a field or property, but both provide a type and setter action
                ExtractMemberInfo(member, out Type memberType, out Action <object, object> memberSetter);

                if (memberType != null && memberSetter != null)
                {
                    // Check if the type has already been generated as a parent
                    // If so skip this generation otherwise track it for use later in the object tree
                    if (context.Types.Contains(memberType))
                    {
                        continue;
                    }

                    context.Types.Push(memberType);

                    // Generate a random value and bind it to the instance
                    var generator = AutoGeneratorFactory.GetGenerator(memberType, context);
                    var value     = generator.Generate(context);

                    memberSetter.Invoke(instance, value);

                    // Remove the current type from the type stack so siblings can be created
                    context.Types.Pop();
                }
            }
        }
Exemple #13
0
        object IAutoGenerator.Generate(AutoGenerateContext context)
        {
            var overrideContext = new AutoGenerateOverrideContext(context);

            foreach (var generatorOverride in Overrides)
            {
                // Check if an initialized instance is needed
                if (generatorOverride.Preinitialize && overrideContext.Instance == null)
                {
                    overrideContext.Instance = Generator.Generate(context);
                }

                // Let each override apply updates to the instance
                generatorOverride.Generate(overrideContext);
            }

            return(overrideContext.Instance);
        }
Exemple #14
0
        private void PrepareCreate(AutoGenerateContext context)
        {
            // Check a create handler hasn't previously been set or configured externally
            if (!CreateInitialized && CreateActions[currentRuleSet] == null)
            {
                CreateActions[currentRuleSet] = faker =>
                {
                    // Only auto create if the 'default' rule set is defined for generation
                    // This is because any specific rule sets are expected to handle the full creation
                    if (context.RuleSets.Contains(currentRuleSet))
                    {
                        return(Binder.CreateInstance <TType>(context));
                    }

                    return(DefaultCreateAction.Invoke(faker));
                };

                CreateInitialized = true;
            }
        }
Exemple #15
0
        private void PrepareFinish(AutoGenerateContext context)
        {
            if (!FinishInitialized)
            {
                FinishWith((faker, instance) =>
                {
                    // First resolve the values being set
                    // This is from all the rule sets being used to generate the instance
                    var memberNames = new List <string>();

                    foreach (var ruleSetName in context.RuleSets)
                    {
                        if (Actions.TryGetValue(ruleSetName, out var ruleSet))
                        {
                            memberNames.AddRange(ruleSet.Keys);
                        }
                    }

                    // Extract the unpopulated member infos
                    var members = new List <MemberInfo>();

                    foreach (var member in TypeProperties)
                    {
                        if (!memberNames.Contains(member.Key))
                        {
                            members.Add(member.Value);
                        }
                    }

                    // Finalize the instance population
                    context.Binder.PopulateInstance <TType>(instance, context, members);
                });

                FinishInitialized = true;
            }
        }
        internal static IAutoGenerator ResolveGenerator(AutoGenerateContext context)
        {
            var type = context.GenerateType;

            // Need check if the type is an in/out parameter and adjusted accordingly
            if (type.IsByRef)
            {
                type = type.GetElementType();
            }

            // Check if an expando object needs to generator
            // This actually means an existing dictionary needs to be populated
            if (ReflectionHelper.IsExpandoObject(type))
            {
                return(new ExpandoObjectGenerator());
            }

            // Do some type -> generator mapping
            if (type.IsArray)
            {
                type = type.GetElementType();
                return(CreateGenericGenerator(typeof(ArrayGenerator <>), type));
            }

#if !NETSTANDARD1_3
            if (DataTableGenerator.TryCreateGenerator(type, out var dataTableGenerator))
            {
                return(dataTableGenerator);
            }

            if (DataSetGenerator.TryCreateGenerator(type, out var dataSetGenerator))
            {
                return(dataSetGenerator);
            }
#endif

            if (ReflectionHelper.IsEnum(type))
            {
                return(CreateGenericGenerator(typeof(EnumGenerator <>), type));
            }

            if (ReflectionHelper.IsNullable(type))
            {
                type = ReflectionHelper.GetGenericArguments(type).Single();
                return(CreateGenericGenerator(typeof(NullableGenerator <>), type));
            }

            Type genericCollectionType = ReflectionHelper.GetGenericCollectionType(type);

            if (genericCollectionType != null)
            {
                // For generic types we need to interrogate the inner types
                var generics = ReflectionHelper.GetGenericArguments(genericCollectionType);

                if (ReflectionHelper.IsReadOnlyDictionary(genericCollectionType))
                {
                    var keyType   = generics.ElementAt(0);
                    var valueType = generics.ElementAt(1);

                    return(CreateGenericGenerator(typeof(ReadOnlyDictionaryGenerator <,>), keyType, valueType));
                }

                if (ReflectionHelper.IsDictionary(genericCollectionType))
                {
                    return(CreateDictionaryGenerator(generics));
                }

                if (ReflectionHelper.IsList(genericCollectionType))
                {
                    var elementType = generics.Single();
                    return(CreateGenericGenerator(typeof(ListGenerator <>), elementType));
                }

                if (ReflectionHelper.IsSet(genericCollectionType))
                {
                    var elementType = generics.Single();
                    return(CreateGenericGenerator(typeof(SetGenerator <>), elementType));
                }

                if (ReflectionHelper.IsCollection(genericCollectionType))
                {
                    var elementType = generics.Single();
                    return(CreateGenericGenerator(typeof(ListGenerator <>), elementType));
                }

                if (ReflectionHelper.IsEnumerable(genericCollectionType))
                {
                    // Not a full list type, we can't fake it if it's anything other than
                    // the actual IEnumerable<T> interface itelf.
                    if (type == genericCollectionType)
                    {
                        var elementType = generics.Single();
                        return(CreateGenericGenerator(typeof(EnumerableGenerator <>), elementType));
                    }
                }
            }

            // Resolve the generator from the type
            if (Generators.ContainsKey(type))
            {
                return(Generators[type]);
            }

            return(CreateGenericGenerator(typeof(TypeGenerator <>), type));
        }
        private static IAutoGenerator ResolveGenerator(AutoGenerateContext context)
        {
            var type = context.GenerateType;

            // Need check if the type is an in/out parameter and adjusted accordingly
            if (type.IsByRef)
            {
                type = type.GetElementType();
            }

            // Check if an expando object needs to generator
            // This actually means an existing dictionary needs to be populated
            if (ReflectionHelper.IsExpandoObject(type))
            {
                return(new ExpandoObjectGenerator());
            }

            // Do some type -> generator mapping
            if (type.IsArray)
            {
                type = type.GetElementType();
                return(CreateGenericGenerator(typeof(ArrayGenerator <>), type));
            }

#if !NETSTANDARD1_3
            if (DataTableGenerator.TryCreateGenerator(type, out var dataTableGenerator))
            {
                return(dataTableGenerator);
            }

            if (DataSetGenerator.TryCreateGenerator(type, out var dataSetGenerator))
            {
                return(dataSetGenerator);
            }
#endif

            if (ReflectionHelper.IsEnum(type))
            {
                return(CreateGenericGenerator(typeof(EnumGenerator <>), type));
            }

            if (ReflectionHelper.IsGenericType(type))
            {
                // For generic types we need to interrogate the inner types
                var generics = ReflectionHelper.GetGenericArguments(type);

                if (ReflectionHelper.IsReadOnlyDictionary(type))
                {
                    var keyType   = generics.ElementAt(0);
                    var valueType = generics.ElementAt(1);

                    return(CreateGenericGenerator(typeof(ReadOnlyDictionaryGenerator <,>), keyType, valueType));
                }

                if (ReflectionHelper.IsDictionary(type))
                {
                    return(CreateDicitonaryGenerator(generics));
                }

                if (ReflectionHelper.IsSet(type))
                {
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(SetGenerator <>), type));
                }

                if (ReflectionHelper.IsEnumerable(type))
                {
                    // If the type has more than one generic use a dictionary (hasn't been resolved by dictionary check above)
                    // Example is a Dictionary<T, U>.KeyCollection
                    if (generics.Count() == 2)
                    {
                        return(CreateDicitonaryGenerator(generics));
                    }

                    // Otherwise it is a list type
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(EnumerableGenerator <>), type));
                }

                if (ReflectionHelper.IsNullable(type))
                {
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(NullableGenerator <>), type));
                }
            }

            // Resolve the generator from the type
            if (Generators.ContainsKey(type))
            {
                return(Generators[type]);
            }

            return(CreateGenericGenerator(typeof(TypeGenerator <>), type));
        }
Exemple #18
0
        private static IAutoGenerator ResolveGenerator(AutoGenerateContext context)
        {
            // Do some type -> generator mapping
            var type = context.GenerateType;

            if (type.IsArray)
            {
                type = type.GetElementType();
                return(CreateGenericGenerator(typeof(ArrayGenerator <>), type));
            }

            if (ReflectionHelper.IsEnum(type))
            {
                return(CreateGenericGenerator(typeof(EnumGenerator <>), type));
            }

            if (ReflectionHelper.IsGenericType(type))
            {
                // For generic types we need to interrogate the inner types
                var generics = ReflectionHelper.GetGenericArguments(type);

                if (ReflectionHelper.IsReadOnlyDictionary(type))
                {
                    var keyType   = generics.ElementAt(0);
                    var valueType = generics.ElementAt(1);

                    return(CreateGenericGenerator(typeof(ReadOnlyDictionaryGenerator <,>), keyType, valueType));
                }

                if (ReflectionHelper.IsDictionary(type))
                {
                    return(CreateDicitonaryGenerator(generics));
                }

                if (ReflectionHelper.IsSet(type))
                {
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(SetGenerator <>), type));
                }

                if (ReflectionHelper.IsEnumerable(type))
                {
                    // If the type has more than one generic use a dictionary (hasn't been resolved by dictionary check above)
                    // Example is a Dictionary<T, U>.KeyCollection
                    if (generics.Count() == 2)
                    {
                        return(CreateDicitonaryGenerator(generics));
                    }

                    // Otherwise it is a list type
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(EnumerableGenerator <>), type));
                }

                if (ReflectionHelper.IsNullable(type))
                {
                    type = generics.Single();
                    return(CreateGenericGenerator(typeof(NullableGenerator <>), type));
                }
            }

            // Resolve the generator from the type
            if (Generators.ContainsKey(type))
            {
                return(Generators[type]);
            }

            return(CreateGenericGenerator(typeof(TypeGenerator <>), type));
        }
        internal static IAutoGenerator GetGenerator <TType>(AutoGenerateContext context)
        {
            var type = typeof(TType);

            return(GetGenerator(type, context));
        }
Exemple #20
0
 public override bool CanOverride(AutoGenerateContext context)
 {
     return(context.ParentType == Type && MemberName.Equals(context.GenerateName, StringComparison.OrdinalIgnoreCase));
 }
Exemple #21
0
 public override bool CanOverride(AutoGenerateContext context)
 {
     return(context.GenerateType == Type);
 }