using System.Collections.Generic;
using System.Xml.Serialization;
public static void Main()
var exporters = new Dictionary<ExportTypes, IProductsExporter>
{ ExportTypes.Json, new JsonProductsExporter() },
{ ExportTypes.Xml, new XmlProductsExporter() },
{ ExportTypes.Csv, new CsvProductsExporterAdapter(new CsvHelper(';')) }
Console.WriteLine("Please select one:");
.Select((e, i) => $"{i + 1}. {e.Key}")
.Aggregate((x, y) => x + Environment.NewLine + y));
var key = Console.ReadLine()!;
var hasKey = exporters.TryGetValue(Enum.Parse<ExportTypes>(key), out var productExporter);
var products = new List<Product>
Title = "MacBook Pro 14 inch",
Description = "It's now even more capable, thanks to the new M3 chip."
Title = "MacBook Pro 16 inch",
Description = "It's now even more capable, thanks to the new M3 chip."
var data = productExporter.Export(products);
public string Title { get; set; }
public string Description { get; set; }
public interface IProductsExporter
string Export(List<Product> products);
public class XmlProductsExporter : IProductsExporter
public string Export(List<Product> products)
var xmlSerializer = new XmlSerializer(products.GetType());
using var stringWriter = new StringWriter();
using var xmlWriter = new XmlTextWriter(stringWriter) { Formatting = Formatting.Indented };
xmlSerializer.Serialize(xmlWriter, products);
return stringWriter.ToString();
public class JsonProductsExporter : IProductsExporter
public string Export(List<Product> products)
return JsonSerializer.Serialize(products);
public class CsvProductsExporterAdapter : IProductsExporter
private CsvHelper CsvHelper { get; set; }
public CsvProductsExporterAdapter(CsvHelper csvHelper)
public string Export(List<Product> data)
return CsvHelper.GenerateCsv(data.Cast<object>().ToList());
private char Delimiter { get; set; }
public CsvHelper(char delimiter)
public string GenerateCsv(List<object> rows)
if (rows == null) return string.Empty;
var objectType = rows.FirstOrDefault()!.GetType();
var headers = objectType.GetProperties().Select(x => x.Name).ToList();
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine(string.Join(Delimiter, headers));
foreach (var row in rows)
var values = objectType.GetProperties().Select(prop => prop.GetValue(row)).ToList();
stringBuilder.AppendLine(string.Join(Delimiter, values));
return stringBuilder.ToString();