Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…utobogus into feat/DateTimeKind-support
  • Loading branch information
soenneker committed Jan 28, 2024
2 parents 9902e67 + 0529916 commit e0feabd
Show file tree
Hide file tree
Showing 24 changed files with 270 additions and 450 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,7 @@ MigrationBackup/

# Fody - auto-generated XML schema
FodyWeavers.xsd

# JetBrains Rider
.idea/
*.sln.iml
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
[![](https://img.shields.io/nuget/dt/soenneker.utils.autobogus.svg?style=for-the-badge)](https://www.nuget.org/packages/soenneker.utils.autobogus/)

# ![](https://user-images.githubusercontent.com/4441470/224455560-91ed3ee7-f510-4041-a8d2-3fc093025112.png) Soenneker.Utils.AutoBogus
### The .NET Bogus autogenerator
### The .NET Autogenerator

This project is a replacement for the abandoned [AutoBogus](https://github.com/nickdodd79/AutoBogus) library. It's mostly plug and play. It aims to be fast, and support the latest types in .NET.
This project is an automatic creator and populator for the fake data generator [Bogus](https://github.com/bchavez/Bogus).

It's a replacement for the abandoned [AutoBogus](https://github.com/nickdodd79/AutoBogus) library. It's mostly plug and play.

The goals are to be *fast*, and support the latest types in .NET.

.NET Standard 2.1 is required.

Expand Down
5 changes: 5 additions & 0 deletions src/Abstract/IAutoFakerBinder.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Reflection;
using Bogus;
using Soenneker.Utils.AutoBogus.Context;
Expand All @@ -17,6 +18,8 @@ public interface IAutoFakerBinder : IBinder
/// <returns>The created instance.</returns>
TType? CreateInstance<TType>(AutoFakerContext context);

object? CreateInstance(AutoFakerContext context, Type type);

/// <summary>
/// Populates the provided instance with generated values.
/// </summary>
Expand All @@ -29,4 +32,6 @@ public interface IAutoFakerBinder : IBinder
/// values are applied to the provided instance and not a copy.
/// </remarks>
void PopulateInstance<TType>(object instance, AutoFakerContext context, MemberInfo[]? members = null);

void PopulateInstance(object instance, AutoFakerContext context, Type type, MemberInfo[]? members = null);
}
101 changes: 101 additions & 0 deletions src/AutoFakerBinder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using Soenneker.Reflection.Cache.Constructors;
Expand Down Expand Up @@ -50,6 +51,49 @@ public class AutoFakerBinder : Binder, IAutoFakerBinder

}

public object? CreateInstance(AutoFakerContext? context, Type type)
{
if (context == null)
return default;

CachedConstructor? constructor = GetConstructor(context.CachedType);

if (constructor == null)
return default;

ParameterInfo[] parametersInfo = constructor.GetParameters();
var parameters = new object[parametersInfo.Length];

for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = GetParameterGenerator(type, parametersInfo[i], context).Generate(context);
}

return constructor.Invoke(parameters);
}

public virtual TType? CreateInstance<TType>(AutoFakerContext? context, Type type)
{
if (context == null)
return default;

CachedConstructor? constructor = GetConstructor(context.CachedType);

if (constructor == null)
return default;

ParameterInfo[] parametersInfo = constructor.GetParameters();
var parameters = new object[parametersInfo.Length];

for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = GetParameterGenerator(type, parametersInfo[i], context).Generate(context);
}

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

}

/// <summary>
/// Populates the provided instance with generated values.
/// </summary>
Expand Down Expand Up @@ -120,6 +164,63 @@ public virtual void PopulateInstance<TType>(object? instance, AutoFakerContext?
}
}

public void PopulateInstance(object instance, AutoFakerContext context, Type type, MemberInfo[]? members = null)
{
// We can only populate non-null instances
if (instance == null || context == null)
{
return;
}

CachedType cachedType = CacheService.Cache.GetCachedType(type);

// Iterate the members and bind a generated value
List<AutoMember> autoMembers = GetMembersToPopulate(cachedType, members);

foreach (AutoMember? member in autoMembers)
{
if (member.Type != null)
{
// Check if the member has a skip config or 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 (ShouldSkip(member.Type, $"{type.FullName}.{member.Name}", context))
{
continue;
}

context.Setup(type, member.Type, member.Name);

context.TypesStack.Push(member.Type);

// Generate a random value and bind it to the instance
IAutoFakerGenerator generator = GeneratorFactory.GetGenerator(context);
object value = generator.Generate(context);

try
{
if (!member.IsReadOnly)
{
member.Setter.Invoke(instance, value);
}
else if (member.CachedType.IsDictionary())
{
PopulateDictionary(value, instance, member);
}
else if (member.CachedType.IsCollection())
{
PopulateCollection(value, instance, member);
}
}
catch
{
}

// Remove the current type from the type stack so siblings can be created
context.TypesStack.Pop();
}
}
}

private static bool ShouldSkip(Type type, string path, AutoFakerContext context)
{
// Skip if the type is found
Expand Down
Loading

0 comments on commit e0feabd

Please sign in to comment.