Skip to content

Simpler way to reference generated values #5

Description

@Atulin

The current way of using .Memo(ref) is great, since the memo can be inserted anywhere in the generator chain. However, needing .Memo(), .Func(), and an out-of-scope MemoValueGenerator<string> ref = null! variable is pretty dang verbose:

MemoValueGenerator<string> ref = null!;
_ = new ThingFaker
{
    Foo = f => f.Random.Number(0, 10).Memo(ref),
    Bar = f => f.Basic.Func(() => $"foo is {ref}"),
};

With the 1.0 release, however, and [Faker<T>] support, there is some potential to introduce less powerful but easier way of handling references. I'd imagine code like

[Faker<Thing>]
public partial sealed class ThingFaker
{
    [DependsOn(nameof(Foo))]
    public override Func<Forge, IGenerator<string>> Bar { get; init; }
}
With a delegate?
public delegate Forger<T>(Forge forge, IGenerator<T> generator);
[Faker<Thing>]
public partial sealed class ThingFaker
{
    [DependsOn(nameof(Foo))]
    public override Forger<string> Bar { get; init; }
}

or

[Faker<Thing>]
[DependsOn(nameof(Thing.Bar), nameof(Thing.Foo))]
public partial sealed class ThingFaker;

could generate code akin to

public partial class ThingFaker
{
    public required virtual Func<Forge, IGenerator<int>> Foo { get; init; }
    public required virtual Func<Forge, int, IGenerator<string>> Bar { get; init; }
}

which would let the user do

_ = new ThingFaker
{
    Foo = f => f.Random.Number(0, 10),
    Bar = (f, foo) => f.Basic.Literal($"foo is {foo}"),
};

Arguably, it merely moves the complexity from the callsite to declaration site, but perhaps it's a worthy endeavour?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions