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) => { #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; } }
/// <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);
/// <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)); }
/// <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(); } } }
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.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.Skips.Any(s => s == path); if (!existing) { context.Config.Skips.Add(path); } } } // Get the type generator var generator = AutoGeneratorFactory.GetGenerator(context); return((TType)generator.Generate(context)); } return(DefaultCreateAction.Invoke(faker)); }; CreateInitialized = true; } }
/// <summary> /// Creates an instance of type <typeparamref name="TType"/>. /// </summary> /// <typeparam name="TType">The instance type to generate.</typeparam> /// <returns>An instance of <typeparamref name="TType"/>.</returns> public TType Generate <TType>() { var generator = AutoGeneratorFactory.GetGenerator <TType>(this); return((TType)generator.Generate(this)); }