From 21083b3f8d8f70172146fb7e425c07096eb2e9cf Mon Sep 17 00:00:00 2001 From: Jon Saffron Date: Fri, 21 Jun 2024 23:11:46 +0100 Subject: [PATCH] Add AttributeCollection.AddOrReplace --- FacadeFor3e.Tests/AttributeCollectionTests.cs | 24 +++++++++++++++ FacadeFor3e.Tests/FacadeFor3e.Tests.csproj | 2 +- FacadeFor3e/FacadeFor3e.csproj | 2 +- .../AttributeCollection.cs | 30 ++++++++++++++----- FacadeFor3e/ReleaseHistory.md | 6 +++- 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/FacadeFor3e.Tests/AttributeCollectionTests.cs b/FacadeFor3e.Tests/AttributeCollectionTests.cs index 0c11105..d17d6d5 100644 --- a/FacadeFor3e.Tests/AttributeCollectionTests.cs +++ b/FacadeFor3e.Tests/AttributeCollectionTests.cs @@ -164,6 +164,30 @@ public void SetAnItem() ClassicAssert.AreEqual(n, coll[0]); } + [Test] + public void TestSetOrReplace() + { + var coll = new AttributeCollection + { + new NamedAttributeValue("boolean", new BoolAttribute(true)), + new NamedAttributeValue("integer", new IntAttribute(25)), + new NamedAttributeValue("guid", new GuidAttribute(Guid.NewGuid())) + }; + + var g = new NamedAttributeValue("guid", new BoolAttribute(true)); + var i = new NamedAttributeValue("integer", new IntAttribute(25)); + var t = new NamedAttributeValue("date", new DateTimeAttribute(DateTime.Now)); + + coll.AddOrReplace(g); + coll.AddOrReplace(i); + coll.AddOrReplace(t); + + ClassicAssert.AreEqual(4, coll.Count); + ClassicAssert.AreEqual(g, coll["guid"]); + ClassicAssert.AreEqual(i, coll["integer"]); + ClassicAssert.AreEqual(t, coll["date"]); + } + [Test] public void GetErrors() { diff --git a/FacadeFor3e.Tests/FacadeFor3e.Tests.csproj b/FacadeFor3e.Tests/FacadeFor3e.Tests.csproj index 6a9b454..27f1dca 100644 --- a/FacadeFor3e.Tests/FacadeFor3e.Tests.csproj +++ b/FacadeFor3e.Tests/FacadeFor3e.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/FacadeFor3e/FacadeFor3e.csproj b/FacadeFor3e/FacadeFor3e.csproj index 5f832f1..3737ee5 100644 --- a/FacadeFor3e/FacadeFor3e.csproj +++ b/FacadeFor3e/FacadeFor3e.csproj @@ -5,7 +5,7 @@ FacadeFor3E J Saffron Consulting FacadeFor3E - 4.0.0-rc3 + 4.0.0 A library that makes integrating with Elite 3E a little easier Copyright © J Saffron Consulting Ltd 2014 - 2024 https://github.com/JonSaffron/FacadeFor3e diff --git a/FacadeFor3e/ProcessCommandBuilder/AttributeCollection.cs b/FacadeFor3e/ProcessCommandBuilder/AttributeCollection.cs index 14e1ee3..77c7e8c 100644 --- a/FacadeFor3e/ProcessCommandBuilder/AttributeCollection.cs +++ b/FacadeFor3e/ProcessCommandBuilder/AttributeCollection.cs @@ -24,7 +24,6 @@ public NamedAttributeValue this[string name] { if (name == null) throw new ArgumentNullException(nameof(name)); - // ReSharper disable once PossibleNullReferenceException var result = this.SingleOrDefault(a => a.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); if (result == null) throw new KeyNotFoundException("An attribute could not be found with the specified name."); @@ -42,18 +41,39 @@ public bool TryGetValue(string name, [NotNullWhen(true)] out NamedAttributeValue { if (name == null) throw new ArgumentNullException(nameof(name)); - // ReSharper disable once PossibleNullReferenceException namedAttribute = this.SingleOrDefault(a => a.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); return namedAttribute != null; } + /// + /// Adds the specified attribute to the collection, or replaces it if an attribute with the same name is already present + /// + /// The attribute to add or to replace + /// If is null + public void AddOrReplace(NamedAttributeValue namedAttribute) + { + if (namedAttribute == null) throw new ArgumentNullException(nameof(namedAttribute)); + for (int i = 0; i < this.Count; i++) + { + var a = this[i]; + + if (a.Name.Equals(namedAttribute.Name, StringComparison.OrdinalIgnoreCase)) + { + // ReSharper disable once RedundantBaseQualifier + this.SetItem(i, namedAttribute); + return; + } + } + + base.Add(namedAttribute); + } + /// // ReSharper disable once AnnotationConflictInHierarchy protected override void InsertItem(int index, NamedAttributeValue item) { if (item == null) throw new ArgumentNullException(nameof(item)); - // ReSharper disable once PossibleNullReferenceException if (this.Any(a => a.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase))) throw new ArgumentOutOfRangeException($"An attribute with the name {item.Name} has already been added."); base.InsertItem(index, item); @@ -71,8 +91,6 @@ protected override void SetItem(int index, NamedAttributeValue item) continue; var a = this[i]; - if (a == null) - throw new InvalidOperationException(); if (a.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase)) throw new ArgumentOutOfRangeException($"An attribute with the name {item.Name} already exists."); } @@ -94,8 +112,6 @@ public bool Remove(string name) { var a = this[i]; - if (a == null) - throw new InvalidOperationException(); if (a.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) { // ReSharper disable once RedundantBaseQualifier diff --git a/FacadeFor3e/ReleaseHistory.md b/FacadeFor3e/ReleaseHistory.md index d3a365e..8df27f7 100644 --- a/FacadeFor3e/ReleaseHistory.md +++ b/FacadeFor3e/ReleaseHistory.md @@ -1,4 +1,8 @@ -4.0.0-rc3 +4.0.0 +----- +Added AddOrReplace to AttributeCollection to serve a particular use case + +4.0.0-rc3 --------- Change the ODataServiceResult.ErrorMesssages property to make it less brittle and enable it to cope with errors caused by rate limiting Updated the json deserialiser to be case-insensitive and to cache the options object