From dd8c483d8ab0f65edc07cf5a45b25566d5f39c42 Mon Sep 17 00:00:00 2001
From: Mike-E <michael@dragonspark.network>
Date: Sun, 12 Mar 2023 10:32:59 -0400
Subject: [PATCH] Removed target instances from cache after first access

---
 .../Instances/ExistingInstanceExtension.cs    |  12 +-
 .../Issue599Tests.cs                          | 164 ++++++++++++++++++
 2 files changed, 172 insertions(+), 4 deletions(-)
 create mode 100644 test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue599Tests.cs

diff --git a/src/ExtendedXmlSerializer/ExtensionModel/Instances/ExistingInstanceExtension.cs b/src/ExtendedXmlSerializer/ExtensionModel/Instances/ExistingInstanceExtension.cs
index 88e9c60f0..7abc20873 100644
--- a/src/ExtendedXmlSerializer/ExtensionModel/Instances/ExistingInstanceExtension.cs
+++ b/src/ExtendedXmlSerializer/ExtensionModel/Instances/ExistingInstanceExtension.cs
@@ -40,12 +40,16 @@ public Reader(IReader reader, IInstances instances)
 
 				public object Get(IFormatReader parameter)
 				{
-					var key = parameter.Get()
-					                   .AsValid<XmlReader>();
+					var key = parameter.Get().AsValid<XmlReader>();
 
-					var result = _instances.IsSatisfiedBy(key) ? _instances.Get(key) : _reader.Get(parameter);
+					if (_instances.IsSatisfiedBy(key))
+					{
+						var result = _instances.Get(key);
+						_instances.Remove(key);
+						return result;
+					}
 
-					return result;
+					return _reader.Get(parameter);
 				}
 			}
 		}
diff --git a/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue599Tests.cs b/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue599Tests.cs
new file mode 100644
index 000000000..ca2b9ebe9
--- /dev/null
+++ b/test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue599Tests.cs
@@ -0,0 +1,164 @@
+using ExtendedXmlSerializer.Configuration;
+using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace ExtendedXmlSerializer.Tests.ReportedIssues
+{
+	public sealed class Issue599Tests
+	{
+		[Fact]
+		public void Verify()
+		{
+			var sut = new ConfigurationContainer().AllowTargetInstances().Create().ForTesting();
+
+			var instance = new NewDefinitionView
+			{
+				Name            = "Hello world",
+				Description     = "Does this work?",
+				DescriptionFull = "This is a longer description",
+				Average         = 12345,
+				Market          = MarketClassification.Traditional,
+				Result          = Guid.NewGuid(),
+				Price           = 123.21M,
+				Identifier      = "unique",
+				SimpleMode      = true,
+				Templates = new PackagingTemplateViews
+				{
+					new()
+					{
+						Name   = "Testing",
+						Fields = new List<TemplateField> { new TextField { FullName = "This works now right?", Id = 123 } }
+					}
+				},
+				Gratitude = new BeneficiaryDefinitionView { Enabled = true, Amount = 1234 }
+			};
+			var content = sut.Serialize(instance);
+			var target  = new NewDefinitionView();
+			sut.UsingTarget(target).Deserialize(content).Should().BeEquivalentTo(instance);
+		}
+
+		public sealed class NewDefinitionView : DefinitionView
+		{
+			public Guid? Result { get; set; }
+		}
+
+		public class DefinitionView
+		{
+			public MarketClassification Market { get; set; }
+
+			public string Name { get; set; } = default!;
+
+			public string Description { get; set; } = string.Empty;
+
+			public string DescriptionFull { get; set; }
+
+			public string Identifier { get; set; } = default!;
+
+			public decimal Price { get; set; }
+
+			public decimal Average { get; set; }
+
+			public PackagingTemplateViews Templates { get; set; } = default!;
+
+			public bool SimpleMode { get; set; } = true;
+
+			public BeneficiaryDefinitionView Gratitude { get; set; } = default!;
+		}
+
+		public sealed class BeneficiaryDefinitionView
+		{
+			public bool Enabled { get; set; }
+
+			public float Amount { get; set; } = .1f;
+		}
+
+		public enum MarketClassification : byte
+		{
+			Standard    = 1,
+			Featured    = 2,
+			Treasure    = 3,
+			Traditional = 4,
+			Mature      = 5
+		}
+
+		public sealed class PackagingTemplateViews : SelectedCollection<PackagingTemplate>
+		{
+			public PackagingTemplateViews() : base(Array.Empty<PackagingTemplate>()) {}
+
+			public PackagingTemplateViews(IEnumerable<PackagingTemplate> list) : base(list) {}
+
+			public ICollection<TemplateFieldValue> Values { get; set; } = default!;
+		}
+
+		public class SelectedCollection<T> : List<T>
+		{
+			public SelectedCollection(IEnumerable<T> list) : base(list) {}
+
+			public virtual T Selected { get; set; }
+		}
+
+		public class PackagingTemplate : Template {}
+
+		public abstract class Template
+		{
+			public int Id { get; set; }
+
+			public DateTimeOffset Created { get; set; }
+
+			public string Identifier { get; set; } = default!;
+
+			public string Name { get; set; } = default!;
+
+			public string Description { get; set; }
+
+			public ICollection<TemplateField> Fields { get; set; } = default!;
+		}
+
+		public class TextField : TemplateField
+		{
+			public string FullName { get; set; } = default!;
+		}
+
+		public abstract class TemplateField
+		{
+			public int Id { get; set; }
+
+			public DateTimeOffset Created { get; set; }
+
+			public string Identifier { get; set; } = default!;
+
+			public string Name { get; set; } = default!;
+
+			public string Description { get; set; }
+
+			public bool IsRequired { get; set; }
+		}
+
+		public class TemplateFieldValue
+		{
+			public long Id { get; set; }
+
+			public TemplateField Field { get; set; } = default!;
+
+			public TemplateValue Value { get; set; } = default!;
+
+			public void Deconstruct(out TemplateField field, out TemplateValue value)
+			{
+				field = Field;
+				value = Value;
+			}
+		}
+
+		public abstract class TemplateValue
+		{
+			public long Id { get; set; }
+
+			public bool Enabled { get; set; }
+
+			public TemplateValue Clone() => MemberwiseClone().To<TemplateValue>();
+		}
+	}
+}
\ No newline at end of file