1

I am trying to add an extension method that generates a random HashSet of ints for use with NBuilder mocking library.

This is the method I would like to shorten into a simple extension method:

using System;
using FizzWare.NBuilder;
using System.Collections.Generic;
using System.Linq;

namespace FakeData
{
    public class Person
    {
        public string Name { get; set; }
        public HashSet<int> AssociatedIds { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {

            var people = Builder<Person>.CreateListOfSize(50)
                .All()
                    .With(p => p.AssociatedIds =
                        Enumerable.Range(0, 50)
                            .Select(x => new Tuple<int, int>(new Random().Next(1, 1000), x))
                            .OrderBy(x => x.Item1)
                            .Take(new Random().Next(1, 50))
                            .Select(x => x.Item2)
                            .ToHashSet())
                .Build();
        }
    }
}

I want to replace the With() so it would instead look like:

var people = Builder<Person>.CreateListOfSize(50)
    .All()
        .RandomHashInt(p => p.AssociatedIds, 1, 50)
    .Build();

Something like this:

public static IOperable<T> RandonHashInt<T>(this IOperable<T> record, Expression<Func<T, HashSet<int>>> property, int min, int max)
{
    //add hashset
    return record;
}

Can someone point me in right direction please

Guerrilla
  • 13,375
  • 31
  • 109
  • 210
  • You need to provide a [mcve]. – Enigmativity Feb 20 '18 at 09:59
  • Which part is not clear? I show working code and then the method where I need to add the code but I need help working out how to reference `property` inside `record`. I am not sure how I can make it clearer but if you tell me which part is not clear i will try best to re-write it. – Guerrilla Feb 20 '18 at 10:04
  • I didn't ask it to be clear. I asked for a [mcve]. Did you read that link? I want to be able to copy, paste, and compile your code. – Enigmativity Feb 20 '18 at 10:05
  • I did read it but I mistook your intentions, my apologies. I thought you were saying it was not clear,. I added the class and reference to question – Guerrilla Feb 20 '18 at 10:08
  • Could you please help me with being able to copy, paste, and compile your code? Right now I can't do that. – Enigmativity Feb 20 '18 at 10:33
  • I added namespace, you can copy now without having to change anything but you will have to add the NBuilder and Faker.Net nuget package to compile – Guerrilla Feb 20 '18 at 10:38
  • "CS0234 The type or namespace name 'NameFaker' does not exist in the namespace 'Faker' (are you missing an assembly reference?)" – Enigmativity Feb 20 '18 at 10:41
  • For me NBuilder seems to reference it when it is installed but it's actually not relevant to the extension method so I deleted it. Please take updated code – Guerrilla Feb 20 '18 at 10:44
  • Seems that there are multiple faker nuget packages and they expose the methods through different paths and names. Just adding footnote for the record. – Guerrilla Feb 20 '18 at 10:54
  • You need to change `Func> property` to `Expression>> property` - then you can use reflection to get the proeprty name and then use `PropertyInfo.SetValue`. – Enigmativity Feb 20 '18 at 11:08
  • I can see how to get the property name but cant see how I can use `PropertyInfo.SetValue` on `record`. Can you give me another hint? – Guerrilla Feb 20 '18 at 11:32
  • Nevermind, I found a different solution – Guerrilla Feb 20 '18 at 11:49
  • You should not "new up" a random each time. Create a static / member variable one once and reuse it - else the random numbers will contain many identical runs. You can shorten your creation of randomness to : `.With(p => p.AssociatedIds = new HashSet (Enumerable.Range(0, 50).OrderBy(e => Guid.NewGuid().GetHashCode()).Take(r.Next(1, 50)))` with `static Random r == new Random();` somewhere in your class. – Patrick Artner Feb 20 '18 at 11:51
  • Great tip, I updated my answer – Guerrilla Feb 20 '18 at 11:59

1 Answers1

1

I looked inside source code on NBuilder With() method and copied the way it was done there:

public static IOperable<T> WithRandonHashInt<T>(this IOperable<T> record, Expression<Func<T, HashSet<int>>> property, int min, int max)
{
    var declaration = record as IDeclaration<T>;

    var rand = new Random();

    declaration.ObjectBuilder.With(property,
                Enumerable.Range(min, max)
                    .OrderBy(e => Guid.NewGuid().GetHashCode())
                    .Take(rand.Next(min, max))
                    .ToHashSet());

    return (IOperable<T>)declaration;
}
Guerrilla
  • 13,375
  • 31
  • 109
  • 210