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; } }
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; } }
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)); }
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); }
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); }
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); }
/// <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)); }
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; } }
/// <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(); } } }
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); }
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; } }
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)); }
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)); }
public override bool CanOverride(AutoGenerateContext context) { return(context.ParentType == Type && MemberName.Equals(context.GenerateName, StringComparison.OrdinalIgnoreCase)); }
public override bool CanOverride(AutoGenerateContext context) { return(context.GenerateType == Type); }