diff --git a/creational/prototype/PrototypeSample.cs b/creational/prototype/PrototypeSample.cs index 014676e..e462275 100644 --- a/creational/prototype/PrototypeSample.cs +++ b/creational/prototype/PrototypeSample.cs @@ -1,5 +1,8 @@ using System; +using System.Runtime.Serialization.Formatters.Binary; using System.Threading.Tasks; +using System.IO; +using System.Xml.Serialization; namespace design_patterns.creational.prototype { @@ -13,7 +16,69 @@ namespace design_patterns.creational.prototype public static async Task Run() { Console.WriteLine("Creational - Prototype"); + Product p1 = new Product { + Name = "Product 1", + Details = "details 1", + Price = 44.22m, + DiscountPercentLevel1 = 5, + DiscountPercentLevel2 = 10 + }; + Console.WriteLine($"p1 -> {p1}"); + + // var p2 = p1.DeepCopyWithBinaryFormatter(); + var p2 = p1.DeepCopyWithXmlFormatter(); + p2.Name = "Product 2"; + p2.Price = 11.22m; + Console.WriteLine($"p2 -> {p2}"); + } + } + + public static class PrototypeExtensions { + + // deep copy with binaryformatter + // ATTENTION ! + // - https://docs.microsoft.com/en-gb/dotnet/standard/serialization/binaryformatter-security-guide + // - every type has to be serializable + public static T DeepCopyWithBinaryFormatter(this T from) { + var formatter = new BinaryFormatter(); + using(var stream = new MemoryStream()) { + formatter.Serialize(stream, from); + stream.Seek(0, SeekOrigin.Begin); + return (T)formatter.Deserialize(stream); + } + } + + + /// + /// Better alternative for security concern + /// + /// original object + /// type of original object + /// + public static T DeepCopyWithXmlFormatter(this T from) { + var serializer = new XmlSerializer(typeof(T)); + using(var stream = new MemoryStream()) { + serializer.Serialize(stream, from); + stream.Seek(0, SeekOrigin.Begin); + return (T)serializer.Deserialize(stream); + } + } + } + + // [Serializable] + public class Product { + public string Name { get; set; } + public string Details { get; set; } + + public decimal Price { get; set; } + public int DiscountPercentLevel1 { get; set; } + public int DiscountPercentLevel2 { get; set; } + + + public override string ToString() + { + return $"{Name} : {Details} : {Price} : {DiscountPercentLevel1} : {DiscountPercentLevel2}"; } } } \ No newline at end of file