SeedPacket 5.0

SeedPacket Illustration


SeedPacket is for quickly seeding data in .net for graphic mockups, Rapid Application Development (RAD), unit testing, prototyping, data generation, database seeding, and unit testing. Written in C#, it is easy to use, with a customizable, and powerful rules engine that can pull data from an external source such as an Xml/Json file or string.

How It Works

Similar to a LINQ statement, SeedPacket adds a .seed() extension method onto IEnumerable that fills the list with fully populated elements. The rules engine keys off the datatype or interface, and name of an item's properties so that the instance is filled with data that is appropriate to that type. That is to say, "out-of-the-box", email properties will be filled with valid emails, phone numbers filled with phone numbers, and names are names etc.

By default, the rules engine loads up about 30 rules for common situations and will degrade to more generic rules if necessary. If you need to modify the default generated data, the rules are simple to create and modify, and come with a many examples, including using a data generator that pulls from an external source. The randomly generated data can be set to always be static across requests or to be random for each time.

Simple Examples

Creating seed data is as simple as importing SeedPacket from Nuget, adding the SeedPacket.Extensions namespace, and calling .Seed() on an existing an IEnumerable such as List, etc. The table on the right was generated the code in the second example below.

Be sure to import the SeedPacket.Extensions namespace.
// Example 'User' Class public class User { public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public DateTime Created { get; set; } } // Creates 10 rows (default) var users = new List<User>().Seed(); // Create 20 rows (shown to right) var users = new List<User>().Seed(20); // Create rows starting with 100 to 200 var users = new List<User>().Seed(100, 200);

You can change the number of rows generated by changing the "rows" number to the right and the page will use javascript to fetch a new list of users generated by SeedPacket on the server. Note that even though the seed records are "randomly" generated, the list begins with the same results on subsequent iterations. This is because we are passing in the same random "seed" integer by default. Now change the "seed" number to the right and you will see that the generated data is always the same for a particular number.

You will see how this can be easily customized when we update what data is generated with some custom rules in the Rules engine. The base data is taken from an embedded datasource, which can be easily overridden with an external XML / Json string or file.

Notice how the seed data generated are well-formed usernames and email addresses. The default rules finds that the property type is a "string" and property contains "email" and "username" and generates the appropriate data, including generating the username from the firstname and lastname. Other data types such as the DateTime "Created" or an Int Id are also be created. The rules match first on data-type, then on match on property name with a last-added prioritization.

What happens when you have a field name and/or datatype is not that common? Generally, the basic rules will catch common patterns and use a simple pattern such as the default of Property Name + the RowNumber for string. If there is not even a basic rule for a particular match, generally the type default is returned.

Of course, the real flexibility comes from being able to easily add your own custom rules. We will get to that in the next section, but lets first look at a more advanced example.

Install SeedPacket using the Nuget Package Manager in Visual Studio. From the Package Manager Console type:
PM> Install-Package SeedPacket

For more details:

The SeedPacket source code is available on GitHub.

← Table Scrollsx →
UserId FirstName LastName Email Created
1 Tiffany Campbell 10/07/2020
2 Robert King 03/11/2018
3 Nicholas Scott 06/17/2020
4 Jacqueline Miller 05/31/2018
5 Mary Evans 12/19/2021
6 Treymayne Rodriguez 03/25/2021
7 Omar Harris 09/14/2019
8 Courtney Lee 12/25/2018
9 Jesse Wright 08/19/2018
10 Naomi Wilson 11/03/2021
11 Zoey Rodriguez 06/08/2018
12 Susan Robinson 12/10/2019
13 Denise Scott 07/03/2018
14 Janice Phillips 09/16/2019
15 Patricia Carter 09/22/2020
16 Crystal Lopez 12/01/2020
17 John Hall 01/26/2018
18 Jennifer Hall 03/29/2020
19 Theresa Parker 05/03/2021
20 Gary Baker 12/19/2021
When to use SeedPacket?

You will find that SeedPacket is the most useful when you are in the initial stages of a project and want to rapidly change the structure of data classes without actually having to worry about the data contained in those classes.

A typical development workflow may be:

1. Stub out lists of data using the .Seed method to fill in the structure for your project

2. Create custom Rules to fill in and generate realistic data for mockups and presentations

3. Use SeedPacket for test doubles in your unit tests if desired

4. Migrate to an ORM (Object-Relational Mapping) framework, like Entity Framework, and seed the database using the rules you have created

Designers and UI/UX Developers can focus on designing without worrying about how changes to underlying models and data are affecting their prototypes!

This example passes in 5 additional custom rules into the Rules engine
var generator = new MultiGenerator("~/SourceFiles/xmlSeedSourcePlus.xml") { Rules = { new Rule(typeof(string), "ItemName", g => Funcs.GetNextElement(g, "ProductName"), "ItemName"), new Rule(typeof(int), "SelectedProduct", g => g.RowRandom.Next(0, 11), "Random product id"), new Rule(typeof(string), "Ceo", g => Funcs.GetNextElement(g, "FirstName") + " " + func.NextElement(g, "LastName"), "Random CEO Name"), new Rule(typeof(string),"Description%", g => Funcs.GetRandomElement(g, "Description"), "Description", "Gets Description from custom XML file" ), new Rule(typeof(List<Item>), "", g => Funcs.GetCacheItemsNext<Item>(g, g.Cache.Items, 10, 10, false), "ItemList"), }, BaseDateTime = DateTime.Today, BaseRandom = new Random(1234567) }; generator.Cache.Items = new List<Item>().Seed(1, 10, generator); var examples = new List<Example>().Seed(100, 115, generator);

Advanced Example

For more advanced situations, you can pass in a generator class that contains a customizable rules engine. By default, the "Advanced" ruleset is used which contains about thirty common rules and the data is loaded from an internal resource. In the example below a "MultiGenerator" is injected into the Seed method. We are adding five new rules to modify how the data is created.

The first rule applies to the "ItemName" field uses a built-in seedpacket function (Func) that gets the next element from the datasource list "ProductName". It actually overrides a rule that gets random (fake) products and replaces it with one that gets the next item in the sequence. This insures the values will all be unique, if the number of items requested is less than in the source.

The second rule, randomly picks a selected value for the dropdown from 0 to 10 (the C# Random() method picks values less than the max value).

The third rule, randomly picks a first and last name for any string fields matching "CEO"

The fourth rule, matches any string starting with "Description" and gets a random value from the datasoure called "Description". This is not in the default lists that are "built-in" in SeedPacket. In the constructor for the MultiGenerator, you will see that we are now passing in a custom xml file that has all the source data for our lists. Now we have complete control of our source data and Funcs.RandomElement() can pull from any named element.

The fifth custom rule is the most interesting and makes sure that any List<Item> fields are filled from a generated list that has been saved in the generator's Cache. We can populate this generated list from another .Seed call and this allows us to have complex, hierarchical data when needed. Note how we can initially declare the rules, but then need to make sure we fill the cached data before the rules are actually run.

Lastly, notice how we are setting the BaseDateTime value. This can be used as the starting point for all DateTimes that we generate. We are also setting the BaseRandom value. This is the base of the "Random Tree" that all the other randoms such as the RowRandom property use as theire starting point. If we pass in a Random without a seed value, every call will generate different values. If we pass in a Random with a seed value, the data generated will always be the same. We can always pass in a different number seed number if we do not like the data that we get...

Id Company City State CEO NetWorth Products Description CompanyGuid
100 Next Co Oakleaf GA Collins $139.55M Square, man 54f931a0-3457-8ab6-6224-8aa04175913e
101 Primo Co Pinetown VT John Smith $550.67M Smelly but good e9ce673c-02ad-456e-0107-df6eff29f370
102 Tyrell Washington MT Patricia Johnson $671.91M Awful 9df61b4b-d5d8-38ef-3543-60e298309968
103 Oscorp Greenville NY Michael Williams $804.51M Rich! 90bd1269-0b95-e78f-c1f8-5fda7a1efebd
104 Acme Co Kingston AL Susan Jones $346.52M Who knows d2578136-63d9-99b5-cad8-25cab18dd77a
105 More Co Oakleaf AR William Brown $150.93M Bumpy 0ecd1b54-ca2f-ef87-b9da-c592c03e5848
106 City Inc WestLake PA Mary Davis $48.37M Angular b23c0acb-9db5-f62a-3a95-245ae5ec642e
107 Stark Westmoor AL Robert Miller $138.96M Complicated 1ae50ea5-1291-23a3-7eea-892d3494b888
108 Umbrella Corp Franklin ND Sarah Wilson $703.47M Angular 1aec04dd-1979-de90-7fd2-263933509939
109 More Brighton CO Peter Moore $902.70M Transparent 98a55d7e-ff0d-4cf0-388a-b7dc62066644
110 Wonka Industries Eastdale OH Ann Taylor $65.64M Sunny and bright 4bce7ccb-9b36-82dc-e0fa-5009bb77d5f6
111 Umbrella Franklin ID Roger Anderson $397.28M Squishy 7b7a2b2d-2196-e06b-27f1-2c2ac9db12a3
112 Stark Inc York HI Theresa Thomas $274.48M Light purple 2b379c60-906a-7467-7cdf-5e7484dc4cfa
113 CyberGlobe Corp Peachtree VT Ethan Jackson $684.89M Yellow, definitely yellow ab9205c9-665c-4f83-04a0-d25e4cd6f203
114 Nakatomi Co Oakleaf NY Crystal White $167.43M Hairy and green ed8182f7-8c8a-ab69-0deb-848efc5aaef7
115 Stark Co Gotham AZ Phillip Harris $350.10M Midnight blue 7186dd76-935d-dcb1-65cc-1465cebade03