diff --git a/BuildMultiObjectJson/BuildMultiObjectJson.csproj b/BuildMultiObjectJson/BuildMultiObjectJson.csproj
new file mode 100644
index 0000000..9ed32d6
--- /dev/null
+++ b/BuildMultiObjectJson/BuildMultiObjectJson.csproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
diff --git a/BuildMultiObjectJson/IJsonConvertService.cs b/BuildMultiObjectJson/IJsonConvertService.cs
new file mode 100644
index 0000000..6787e4b
--- /dev/null
+++ b/BuildMultiObjectJson/IJsonConvertService.cs
@@ -0,0 +1,7 @@
+namespace BuildMultiObjectJson
+{
+ public interface IJsonConvertService
+ {
+ void Run();
+ }
+}
\ No newline at end of file
diff --git a/BuildMultiObjectJson/JsonConvertService.cs b/BuildMultiObjectJson/JsonConvertService.cs
new file mode 100644
index 0000000..f03c22e
--- /dev/null
+++ b/BuildMultiObjectJson/JsonConvertService.cs
@@ -0,0 +1,150 @@
+using BuildMultiObjectJson.Models;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using Serilog;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+// DI, Serilog, Settings
+
+namespace BuildMultiObjectJson
+{
+ public class JsonConvertService : IJsonConvertService
+ {
+ private readonly ILogger _log;
+ private readonly IConfiguration _config;
+
+ private List _personTmps = new List();
+ private List _addressTmps = new List();
+ private List _emailAddressTmps = new List();
+ private List _personList = new List();
+ int personRecs = 0;
+ int addressRecs = 0;
+ int nextAddressNr = 0;
+ int emailAddressRecs = 0;
+ int nextEmailAddrNr = 0;
+ Random _random = null;
+
+ public JsonConvertService(ILogger log, IConfiguration config)
+ {
+ _log = log;
+ _config = config;
+ }
+
+ public void Run()
+ {
+ LoadObjectLists();
+ InitPeopleList();
+ AddRandomEmailAddresses(3);
+ AddRandomAddresses(4);
+ RecreatePersonJsonFile();
+ }
+
+ private void RecreatePersonJsonFile()
+ {
+ try
+ {
+ var json = JsonConvert.SerializeObject(_personList);
+ var newFile = _config.GetValue("PathToFiles") + _config.GetValue("GeneratedFile");
+ File.WriteAllText(newFile, json);
+ _log.LogInformation($"{newFile} successfully written ({json.Length} characters)");
+ }
+ catch (Exception ex)
+ {
+ _log.LogError(ex, ex.Message);
+ }
+ }
+
+ private void AddRandomAddresses(int maxAnt)
+ {
+ _personList.ForEach(x =>
+ {
+ if (nextAddressNr < addressRecs)
+ {
+ var Addrs = rndGetNext(maxAnt);
+ x.Addresses.AddRange(_addressTmps.GetRange(nextAddressNr, Addrs));
+ nextAddressNr += Addrs;
+ }
+ });
+ _log.LogInformation($"{nextAddressNr - 1} addresses distributed.");
+ }
+
+ private void AddRandomEmailAddresses(int maxAnt)
+ {
+ _personList.ForEach(x =>
+ {
+ if (nextEmailAddrNr < emailAddressRecs)
+ {
+ var emailAddrs = rndGetNext(maxAnt);
+ x.EmailAddresses.AddRange(_emailAddressTmps.GetRange(nextEmailAddrNr, emailAddrs));
+ nextEmailAddrNr += emailAddrs;
+ }
+ });
+ _log.LogInformation($"{nextEmailAddrNr-1} email addresses distributed.");
+ }
+
+ private void InitPeopleList()
+ {
+ foreach(var pers in _personTmps)
+ {
+ var person = new Person();
+ CopyAll(pers, person);
+ _personList.Add(person);
+ }
+ _log.LogInformation($"{_personList.Count} persons created from tmp-class-list");
+ }
+
+ public void CopyAll(T source, U target)
+ {
+ var sourceProperties = source.GetType().GetProperties();
+ var targetProperties = target.GetType().GetProperties();
+
+ foreach (var sourceProperty in sourceProperties)
+ {
+ foreach (var targetProperty in targetProperties)
+ {
+ if (targetProperty.Name == sourceProperty.Name && targetProperty.PropertyType == sourceProperty.PropertyType)
+ {
+ targetProperty.SetValue(target, sourceProperty.GetValue(source));
+ break;
+ }
+ }
+ }
+
+ }
+
+ private void LoadObjectLists()
+ {
+ _personTmps = Jconvert(_config.GetValue("PathToFiles") + _config.GetValue("PeopleFile"));
+ personRecs = _personTmps.Count;
+ _log.LogInformation($"{personRecs} records converted");
+ _addressTmps = Jconvert(_config.GetValue("PathToFiles") + _config.GetValue("AddressFile"));
+ addressRecs = _addressTmps.Count;
+ _log.LogInformation($"{addressRecs} records converted");
+ _emailAddressTmps = Jconvert(_config.GetValue("PathToFiles") + _config.GetValue("EmailAddressFile"));
+ emailAddressRecs = _emailAddressTmps.Count;
+ _log.LogInformation($"{emailAddressRecs} records converted");
+ }
+
+ static List Jconvert(string fName)
+ {
+ using (StreamReader r = new StreamReader(fName))
+ {
+ string json = r.ReadToEnd();
+ return JsonConvert.DeserializeObject>(json);
+ }
+ }
+
+ private int rndGetNext(int max)
+ {
+ if(_random == null)
+ {
+ _random = new Random();
+ }
+
+ return _random.Next(0, max + 1);
+ }
+ }
+}
diff --git a/BuildMultiObjectJson/Models/AddressTmp.cs b/BuildMultiObjectJson/Models/AddressTmp.cs
new file mode 100644
index 0000000..bf6222d
--- /dev/null
+++ b/BuildMultiObjectJson/Models/AddressTmp.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BuildMultiObjectJson.Models
+{
+ public class AddressTmp
+ {
+ public int Id { get; set; }
+ public string StreetAddress { get; set; }
+ public string City { get; set; }
+ public string State { get; set; }
+ public int ZipCode { get; set; }
+ }
+}
diff --git a/BuildMultiObjectJson/Models/EmailAddressTmp.cs b/BuildMultiObjectJson/Models/EmailAddressTmp.cs
new file mode 100644
index 0000000..5afe0af
--- /dev/null
+++ b/BuildMultiObjectJson/Models/EmailAddressTmp.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BuildMultiObjectJson.Models
+{
+ public class EmailAddressTmp
+ {
+ public int Id { get; set; }
+ public string EmailAddress { get; set; }
+ }
+}
diff --git a/BuildMultiObjectJson/Models/Person.cs b/BuildMultiObjectJson/Models/Person.cs
new file mode 100644
index 0000000..e6679a4
--- /dev/null
+++ b/BuildMultiObjectJson/Models/Person.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BuildMultiObjectJson.Models
+{
+ public class Person
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public int Age { get; set; }
+ public List Addresses { get; set; } = new List();
+ public List EmailAddresses { get; set; } = new List();
+
+ }
+}
diff --git a/BuildMultiObjectJson/Models/PersonTmp.cs b/BuildMultiObjectJson/Models/PersonTmp.cs
new file mode 100644
index 0000000..5e70373
--- /dev/null
+++ b/BuildMultiObjectJson/Models/PersonTmp.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BuildMultiObjectJson.Models
+{
+ public class PersonTmp
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public int Age { get; set; }
+ public string Addresses { get; set; }
+ public string EmailAddresses { get; set; }
+ }
+}
diff --git a/BuildMultiObjectJson/Program.cs b/BuildMultiObjectJson/Program.cs
new file mode 100644
index 0000000..88c9bd9
--- /dev/null
+++ b/BuildMultiObjectJson/Program.cs
@@ -0,0 +1,48 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+using System;
+using System.IO;
+
+// DI, Serilog, Settings
+
+namespace BuildMultiObjectJson
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var builder = new ConfigurationBuilder();
+ BuildConfig(builder);
+
+ Log.Logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(builder.Build())
+ .Enrich.FromLogContext()
+ .WriteTo.Console()
+ .CreateLogger();
+
+ Log.Logger.Information("Application starting");
+
+ var host = Host.CreateDefaultBuilder()
+ .ConfigureServices((context, services) =>
+ {
+ services.AddTransient();
+ })
+ .UseSerilog()
+ .Build();
+
+ var svc = ActivatorUtilities.CreateInstance(host.Services);
+ svc.Run();
+
+ }
+
+ static void BuildConfig(IConfigurationBuilder builder)
+ {
+ builder.SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
+ .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
+ .AddEnvironmentVariables();
+ }
+ }
+}
diff --git a/BuildMultiObjectJson/appsettings.json b/BuildMultiObjectJson/appsettings.json
new file mode 100644
index 0000000..5705545
--- /dev/null
+++ b/BuildMultiObjectJson/appsettings.json
@@ -0,0 +1,17 @@
+{
+ "LoopTimes": 15,
+ "PeopleFile": "People.json",
+ "GeneratedFile": "Generated.json",
+ "AddressFile": "Addresses.json",
+ "EmailAddressFile": "EmailAddresses.json",
+ "PathToFiles": "D:\\CSharpDocuments\\JsonData\\",
+ "Serilog": {
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Information",
+ "System": "Warning"
+ }
+ }
+ }
+}
diff --git a/BuildMultiObjectJsonApp.sln b/BuildMultiObjectJsonApp.sln
new file mode 100644
index 0000000..722ff69
--- /dev/null
+++ b/BuildMultiObjectJsonApp.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30320.27
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildMultiObjectJson", "BuildMultiObjectJson\BuildMultiObjectJson.csproj", "{A4B7B04A-8836-4BBD-B2FF-811B7C80D94D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A4B7B04A-8836-4BBD-B2FF-811B7C80D94D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A4B7B04A-8836-4BBD-B2FF-811B7C80D94D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A4B7B04A-8836-4BBD-B2FF-811B7C80D94D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A4B7B04A-8836-4BBD-B2FF-811B7C80D94D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {12212D25-38B0-44E2-A456-5DBE39BABC4A}
+ EndGlobalSection
+EndGlobal