From 6fc335e6cc5b4b02355c0a1f16b9060704c7bcf6 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:36:47 +0300 Subject: [PATCH 01/11] feat: add empty class members and required models --- ManagedCode.FeatureChecker/Feature.cs | 6 +++ ManagedCode.FeatureChecker/FeatureChecker.cs | 49 ++++++++++++++++++++ ManagedCode.FeatureChecker/FeatureStatus.cs | 8 ++++ 3 files changed, 63 insertions(+) create mode 100644 ManagedCode.FeatureChecker/Feature.cs create mode 100644 ManagedCode.FeatureChecker/FeatureChecker.cs create mode 100644 ManagedCode.FeatureChecker/FeatureStatus.cs diff --git a/ManagedCode.FeatureChecker/Feature.cs b/ManagedCode.FeatureChecker/Feature.cs new file mode 100644 index 0000000..bb59474 --- /dev/null +++ b/ManagedCode.FeatureChecker/Feature.cs @@ -0,0 +1,6 @@ +namespace ManagedCode.FeatureChecker; +public class Feature +{ + public string Name { get; set; } = null!; + public FeatureStatus Status { get; set; } +} diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs new file mode 100644 index 0000000..2b97db0 --- /dev/null +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -0,0 +1,49 @@ +namespace ManagedCode.FeatureChecker; + +public class FeatureChecker +{ + public event EventHandler FeatureAdded; + public event EventHandler FeatureRemoved; + public event EventHandler FeatureStatusChanged; + + public FeatureChecker() { } + + public void AddFeature(string name, FeatureStatus status) + => throw new NotImplementedException(); + + public void AddFeature(Feature feature) + => throw new NotImplementedException(); + + public void AddFutureRange(IEnumerable features) + => throw new NotImplementedException(); + + public void RemoveFeature(string name) + => throw new NotImplementedException(); + + public void RemoveFeature(Feature feature) + => throw new NotImplementedException(); + + public void RemoveFeatureRange(IEnumerable features) + => throw new NotImplementedException(); + + public void RemoveFeatureRange(IEnumerable features) + => throw new NotImplementedException(); + + public bool IsFeatureExists(string name) + => throw new NotImplementedException(); + + public bool IsFeatureEnabled(string name) + => throw new NotImplementedException(); + + public FeatureStatus GetFeatureStatus(string name) + => throw new NotImplementedException(); + + public bool TryGetFeatureStatus(string name, out FeatureStatus status) + => throw new NotImplementedException(); + + public IEnumerable GetExistFeatures(string name) + => throw new NotImplementedException(); + + public IEnumerable GetFeaturesByStatus(FeatureStatus status) + => throw new NotImplementedException(); +} diff --git a/ManagedCode.FeatureChecker/FeatureStatus.cs b/ManagedCode.FeatureChecker/FeatureStatus.cs new file mode 100644 index 0000000..2794f9c --- /dev/null +++ b/ManagedCode.FeatureChecker/FeatureStatus.cs @@ -0,0 +1,8 @@ +namespace ManagedCode.FeatureChecker; + +public enum FeatureStatus +{ + Eanabled, + Disabled, + Debug, +} From 255e9d992fbe7bc508af4542544e3ec84b54f662 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:59:31 +0300 Subject: [PATCH 02/11] feat: implement 'Add..' methods and 'IsFeatureExists' method --- ManagedCode.FeatureChecker/FeatureChecker.cs | 64 +++++++++++++++++--- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index 2b97db0..ba02a28 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -2,20 +2,58 @@ public class FeatureChecker { + private readonly List _features; + + public FeatureChecker() + { + _features = new List(); + } + public event EventHandler FeatureAdded; public event EventHandler FeatureRemoved; public event EventHandler FeatureStatusChanged; - public FeatureChecker() { } + public void AddFeature(string name, FeatureStatus status, bool ignoreDuplicates = true) + { + if(!IsFeatureExists(name)) + { + var feature = new Feature() + { + Name = name, + Status = status + }; - public void AddFeature(string name, FeatureStatus status) - => throw new NotImplementedException(); + _features.Add(feature); + } - public void AddFeature(Feature feature) - => throw new NotImplementedException(); + if(!ignoreDuplicates) + { + throw new ArgumentException($"Feature '{nameof(name)}' is already added."); + } + } - public void AddFutureRange(IEnumerable features) - => throw new NotImplementedException(); + public void AddFeature(Feature feature, bool ignoreDuplicates = true) + { + if(feature == null) + { + throw new ArgumentNullException(nameof(feature), $"Parameter is null."); + } + + AddFeature(feature.Name, feature.Status, ignoreDuplicates); + } + + public void AddFeaturesRange(IEnumerable features, bool ignoreDuplicates = true) + { + if(features == null) + { + throw new ArgumentNullException(nameof(features), $"Parameter is null."); + } + + foreach(var feature in features) + { + AddFeature(feature, ignoreDuplicates); + } + } public void RemoveFeature(string name) => throw new NotImplementedException(); @@ -29,8 +67,16 @@ public void RemoveFeatureRange(IEnumerable features) public void RemoveFeatureRange(IEnumerable features) => throw new NotImplementedException(); - public bool IsFeatureExists(string name) - => throw new NotImplementedException(); + public bool IsFeatureExists(string? name) + { + if(string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException($"Invalid parameter '{nameof(name)}': {name}."); + } + + return _features.Any(x => + x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + } public bool IsFeatureEnabled(string name) => throw new NotImplementedException(); From 0ec484517e79148507e0e307bec90021ad1499d7 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:12:03 +0300 Subject: [PATCH 03/11] feat: add 'UpdateFeatureStatus' methods --- ManagedCode.FeatureChecker/FeatureChecker.cs | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index ba02a28..030195c 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -92,4 +92,26 @@ public IEnumerable GetExistFeatures(string name) public IEnumerable GetFeaturesByStatus(FeatureStatus status) => throw new NotImplementedException(); + + public void UpdateFeatureStatus(string name, FeatureStatus status) + { + if(!IsFeatureExists(name)) + { + throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); + } + + _features.First(x + => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) + .Status = status; + } + + public void UpdateFeatureStatus(Feature feature) + { + if(feature == null) + { + throw new ArgumentNullException(nameof(feature), $"Parameter is null."); + } + + UpdateFeatureStatus(feature.Name, feature.Status); + } } From ccd3645ba01901ddfa059f1c82da16a1c81c5c52 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:34:06 +0300 Subject: [PATCH 04/11] feat: implement methods to get status of a feature --- ManagedCode.FeatureChecker/FeatureChecker.cs | 34 +++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index 030195c..b408fc8 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -79,13 +79,37 @@ public bool IsFeatureExists(string? name) } public bool IsFeatureEnabled(string name) - => throw new NotImplementedException(); + { + var feature = _features.FirstOrDefault(x => + x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); - public FeatureStatus GetFeatureStatus(string name) - => throw new NotImplementedException(); + return feature?.Status == FeatureStatus.Eanabled; + } + + public FeatureStatus GetFeatureStatus(string name) + { + var feature = _features.FirstOrDefault(x => + x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + + if(feature == null) + { + throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); + } + + return feature.Status; + } - public bool TryGetFeatureStatus(string name, out FeatureStatus status) - => throw new NotImplementedException(); + public bool TryGetFeatureStatus(string name, out FeatureStatus status) + { + var feature = _features.FirstOrDefault(x => + x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + + status = feature == null + ? default + : feature.Status; + + return feature != null; + } public IEnumerable GetExistFeatures(string name) => throw new NotImplementedException(); From 8f6810d94bdbd5847fcf58b4f70ea8b7ba37602f Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:37:38 +0300 Subject: [PATCH 05/11] fix(FeatureStatus): change default status from 'Enabled' to 'Disabled' --- ManagedCode.FeatureChecker/FeatureStatus.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ManagedCode.FeatureChecker/FeatureStatus.cs b/ManagedCode.FeatureChecker/FeatureStatus.cs index 2794f9c..46edc00 100644 --- a/ManagedCode.FeatureChecker/FeatureStatus.cs +++ b/ManagedCode.FeatureChecker/FeatureStatus.cs @@ -2,7 +2,7 @@ public enum FeatureStatus { - Eanabled, Disabled, + Eanabled, Debug, } From 30e50dc09c062c8fcaa24cec60d211c49a1d60b7 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:43:59 +0300 Subject: [PATCH 06/11] feat: implement methods to get list of features --- ManagedCode.FeatureChecker/FeatureChecker.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index b408fc8..3f893e6 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -111,11 +111,12 @@ public bool TryGetFeatureStatus(string name, out FeatureStatus status) return feature != null; } - public IEnumerable GetExistFeatures(string name) - => throw new NotImplementedException(); + public IEnumerable GetExistFeatures() => _features.AsReadOnly(); public IEnumerable GetFeaturesByStatus(FeatureStatus status) - => throw new NotImplementedException(); + { + return _features.Where(x => x.Status == status); + } public void UpdateFeatureStatus(string name, FeatureStatus status) { From 544c58d0ac51bb51946fa89543759f1b8a52696b Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 20:17:37 +0300 Subject: [PATCH 07/11] feat: implement methods to remove features --- ManagedCode.FeatureChecker/FeatureChecker.cs | 56 +++++++++++++++++--- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index 3f893e6..4d2bd0d 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -55,17 +55,61 @@ public void AddFeaturesRange(IEnumerable features, bool ignoreDuplicate } } - public void RemoveFeature(string name) - => throw new NotImplementedException(); + public void RemoveFeature(string name, bool ignoreMissing = true) + { + if(IsFeatureExists(name)) + { + var feature = _features.First(x => + x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + + RemoveFeature(feature); + + return; + } + + if(!ignoreMissing) + { + throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); + } + } public void RemoveFeature(Feature feature) - => throw new NotImplementedException(); + { + if(feature == null) + { + throw new ArgumentNullException(nameof(feature), $"Parameter is null."); + } + + _features.Remove(feature); + } + + public void RemoveFeatureRange(IEnumerable features, bool ignoreMissing = true) + { + if(features == null) + { + throw new ArgumentNullException(nameof(features), $"Parameter is null."); + } - public void RemoveFeatureRange(IEnumerable features) - => throw new NotImplementedException(); + foreach(var feature in features) + { + RemoveFeature(feature, ignoreMissing); + } + } public void RemoveFeatureRange(IEnumerable features) - => throw new NotImplementedException(); + { + if(features == null) + { + throw new ArgumentNullException(nameof(features), $"Parameter is null."); + } + + foreach(var feature in features) + { + RemoveFeature(feature); + } + } + + public void RemoveAllFeatures() => _features.Clear(); public bool IsFeatureExists(string? name) { From 22866209dc83139cbfe47e77be6131a250a006aa Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 20:25:50 +0300 Subject: [PATCH 08/11] feat: add method to get 'Feature' by name --- ManagedCode.FeatureChecker/FeatureChecker.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index 4d2bd0d..a0c5bcc 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -183,4 +183,10 @@ public void UpdateFeatureStatus(Feature feature) UpdateFeatureStatus(feature.Name, feature.Status); } + + public Feature? GetFeatureByName(string name) + { + return _features.FirstOrDefault(x => + x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + } } From 0ab042c5db68b47d93b3bff9fe0c20bb4ceb5a72 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Thu, 20 Apr 2023 21:32:52 +0300 Subject: [PATCH 09/11] refactor: refactor most members, remove some ones extract null-checking to the separate method extract name comparing to the separate method remove redundant method 'UpdateFeatureStatus' with model change method 'AddFeature' with model reorder methods add gaps between members --- ManagedCode.FeatureChecker/FeatureChecker.cs | 88 +++++++++----------- 1 file changed, 40 insertions(+), 48 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index a0c5bcc..9b55b22 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -32,36 +32,37 @@ public void AddFeature(string name, FeatureStatus status, bool ignoreDuplicates } } - public void AddFeature(Feature feature, bool ignoreDuplicates = true) + public void AddFeature(Feature newFeature, bool ignoreDuplicates = true) { - if(feature == null) + ThrowIfNull(newFeature, nameof(newFeature)); + + if(!IsFeatureExists(newFeature.Name)) { - throw new ArgumentNullException(nameof(feature), $"Parameter is null."); + _features.Add(newFeature); } - AddFeature(feature.Name, feature.Status, ignoreDuplicates); + if(!ignoreDuplicates) + { + throw new ArgumentException($"Feature '{nameof(newFeature)}' is already added."); + } } - public void AddFeaturesRange(IEnumerable features, bool ignoreDuplicates = true) + public void AddFeaturesRange(IEnumerable newFeatures, bool ignoreDuplicates = true) { - if(features == null) - { - throw new ArgumentNullException(nameof(features), $"Parameter is null."); - } + ThrowIfNull(newFeatures, nameof(newFeatures)); - foreach(var feature in features) + foreach(var feature in newFeatures) { AddFeature(feature, ignoreDuplicates); } } + public void RemoveFeature(string name, bool ignoreMissing = true) { if(IsFeatureExists(name)) { - var feature = _features.First(x => - x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); - + var feature = _features.First(x => AreNamesEqual(name, x)); RemoveFeature(feature); return; @@ -75,20 +76,13 @@ public void RemoveFeature(string name, bool ignoreMissing = true) public void RemoveFeature(Feature feature) { - if(feature == null) - { - throw new ArgumentNullException(nameof(feature), $"Parameter is null."); - } - + ThrowIfNull(feature, nameof(feature)); _features.Remove(feature); } public void RemoveFeatureRange(IEnumerable features, bool ignoreMissing = true) { - if(features == null) - { - throw new ArgumentNullException(nameof(features), $"Parameter is null."); - } + ThrowIfNull(features, nameof(features)); foreach(var feature in features) { @@ -98,10 +92,7 @@ public void RemoveFeatureRange(IEnumerable features, bool ignoreMissing public void RemoveFeatureRange(IEnumerable features) { - if(features == null) - { - throw new ArgumentNullException(nameof(features), $"Parameter is null."); - } + ThrowIfNull(features, nameof(features)); foreach(var feature in features) { @@ -111,29 +102,28 @@ public void RemoveFeatureRange(IEnumerable features) public void RemoveAllFeatures() => _features.Clear(); + public bool IsFeatureExists(string? name) { if(string.IsNullOrWhiteSpace(name)) { - throw new ArgumentNullException($"Invalid parameter '{nameof(name)}': {name}."); + throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); } - return _features.Any(x => - x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + return _features.Any(x => AreNamesEqual(name, x)); } public bool IsFeatureEnabled(string name) { - var feature = _features.FirstOrDefault(x => - x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + var feature = _features.FirstOrDefault(x => AreNamesEqual(name, x)); return feature?.Status == FeatureStatus.Eanabled; } + public FeatureStatus GetFeatureStatus(string name) { - var feature = _features.FirstOrDefault(x => - x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + var feature = _features.FirstOrDefault(x => AreNamesEqual(name, x)); if(feature == null) { @@ -145,8 +135,7 @@ public FeatureStatus GetFeatureStatus(string name) public bool TryGetFeatureStatus(string name, out FeatureStatus status) { - var feature = _features.FirstOrDefault(x => - x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + var feature = _features.FirstOrDefault(x => AreNamesEqual(name, x)); status = feature == null ? default @@ -155,6 +144,12 @@ public bool TryGetFeatureStatus(string name, out FeatureStatus status) return feature != null; } + + public Feature? GetFeatureByName(string name) + { + return _features.FirstOrDefault(x => AreNamesEqual(name, x)); + } + public IEnumerable GetExistFeatures() => _features.AsReadOnly(); public IEnumerable GetFeaturesByStatus(FeatureStatus status) @@ -162,6 +157,7 @@ public IEnumerable GetFeaturesByStatus(FeatureStatus status) return _features.Where(x => x.Status == status); } + public void UpdateFeatureStatus(string name, FeatureStatus status) { if(!IsFeatureExists(name)) @@ -169,24 +165,20 @@ public void UpdateFeatureStatus(string name, FeatureStatus status) throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); } - _features.First(x - => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) - .Status = status; + _features.First(x => AreNamesEqual(name, x)).Status = status; } - public void UpdateFeatureStatus(Feature feature) - { - if(feature == null) - { - throw new ArgumentNullException(nameof(feature), $"Parameter is null."); - } - UpdateFeatureStatus(feature.Name, feature.Status); + private static bool AreNamesEqual(string name, Feature fName) + { + return fName.Name.Equals(name, StringComparison.OrdinalIgnoreCase); } - public Feature? GetFeatureByName(string name) + private static void ThrowIfNull(object obj, string paramName) { - return _features.FirstOrDefault(x => - x.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + if(obj == null) + { + throw new ArgumentNullException(paramName, $"Parameter is null."); + } } } From 90a12bdd483a01f17f51a8e20f2c3a3489195f21 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Fri, 21 Apr 2023 13:02:35 +0300 Subject: [PATCH 10/11] feat: rebuild whole class change inside collection to 'Dictionary' update/change methods according to new inside collection remove redundant methods --- ManagedCode.FeatureChecker/FeatureChecker.cs | 152 +++++-------------- 1 file changed, 41 insertions(+), 111 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index 9b55b22..d27da99 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -2,178 +2,103 @@ public class FeatureChecker { - private readonly List _features; + private readonly Dictionary _features; public FeatureChecker() { - _features = new List(); + _features = new Dictionary(); } public event EventHandler FeatureAdded; public event EventHandler FeatureRemoved; public event EventHandler FeatureStatusChanged; - public void AddFeature(string name, FeatureStatus status, bool ignoreDuplicates = true) - { - if(!IsFeatureExists(name)) - { - var feature = new Feature() - { - Name = name, - Status = status - }; - - _features.Add(feature); - } - - if(!ignoreDuplicates) - { - throw new ArgumentException($"Feature '{nameof(name)}' is already added."); - } - } - public void AddFeature(Feature newFeature, bool ignoreDuplicates = true) + public bool TryAddFeature(string name, FeatureStatus status) { - ThrowIfNull(newFeature, nameof(newFeature)); - - if(!IsFeatureExists(newFeature.Name)) + var feature = new Feature() { - _features.Add(newFeature); - } - - if(!ignoreDuplicates) - { - throw new ArgumentException($"Feature '{nameof(newFeature)}' is already added."); - } - } + Name = name, + Status = status + }; - public void AddFeaturesRange(IEnumerable newFeatures, bool ignoreDuplicates = true) - { - ThrowIfNull(newFeatures, nameof(newFeatures)); - - foreach(var feature in newFeatures) - { - AddFeature(feature, ignoreDuplicates); - } + return TryAddFeature(feature); } - - public void RemoveFeature(string name, bool ignoreMissing = true) + public bool TryAddFeature(Feature newFeature) { - if(IsFeatureExists(name)) - { - var feature = _features.First(x => AreNamesEqual(name, x)); - RemoveFeature(feature); - - return; - } + ThrowIfNull(newFeature, nameof(newFeature)); + ValidateModel(newFeature); - if(!ignoreMissing) - { - throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); - } + return _features.TryAdd(newFeature.Name, newFeature); } - public void RemoveFeature(Feature feature) - { - ThrowIfNull(feature, nameof(feature)); - _features.Remove(feature); - } - public void RemoveFeatureRange(IEnumerable features, bool ignoreMissing = true) + public void RemoveFeature(string name) { - ThrowIfNull(features, nameof(features)); - - foreach(var feature in features) + if(string.IsNullOrWhiteSpace(name)) { - RemoveFeature(feature, ignoreMissing); + throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); } - } - - public void RemoveFeatureRange(IEnumerable features) - { - ThrowIfNull(features, nameof(features)); - foreach(var feature in features) - { - RemoveFeature(feature); - } + _features.Remove(name); } public void RemoveAllFeatures() => _features.Clear(); - public bool IsFeatureExists(string? name) + public bool IsFeatureExists(string name) { if(string.IsNullOrWhiteSpace(name)) { throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); } - return _features.Any(x => AreNamesEqual(name, x)); + return _features.ContainsKey(name); } - public bool IsFeatureEnabled(string name) - { - var feature = _features.FirstOrDefault(x => AreNamesEqual(name, x)); - return feature?.Status == FeatureStatus.Eanabled; - } - - - public FeatureStatus GetFeatureStatus(string name) - { - var feature = _features.FirstOrDefault(x => AreNamesEqual(name, x)); - - if(feature == null) - { - throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); - } - - return feature.Status; - } public bool TryGetFeatureStatus(string name, out FeatureStatus status) { - var feature = _features.FirstOrDefault(x => AreNamesEqual(name, x)); - - status = feature == null - ? default - : feature.Status; + var result = TryGetFeatureByName(name, out Feature? feature); + status = feature?.Status ?? default; - return feature != null; + return result; } - public Feature? GetFeatureByName(string name) + public bool TryGetFeatureByName(string name, out Feature? feature) { - return _features.FirstOrDefault(x => AreNamesEqual(name, x)); + if(string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); + } + + return _features.TryGetValue(name, out feature); } - public IEnumerable GetExistFeatures() => _features.AsReadOnly(); + public Feature[] GetExistFeatures() => _features.Values.ToArray(); public IEnumerable GetFeaturesByStatus(FeatureStatus status) { - return _features.Where(x => x.Status == status); + return _features.Values.Where(x => x.Status == status); } - public void UpdateFeatureStatus(string name, FeatureStatus status) + public bool TryUpdateFeatureStatus(string name, FeatureStatus status) { - if(!IsFeatureExists(name)) + var result = TryGetFeatureByName(name, out Feature? feature); + + if(result && feature != null) { - throw new ArgumentException($"Feature '{nameof(name)}' does not exist."); + feature.Status = FeatureStatus.Disabled; } - _features.First(x => AreNamesEqual(name, x)).Status = status; + return result; } - private static bool AreNamesEqual(string name, Feature fName) - { - return fName.Name.Equals(name, StringComparison.OrdinalIgnoreCase); - } - private static void ThrowIfNull(object obj, string paramName) { if(obj == null) @@ -181,4 +106,9 @@ private static void ThrowIfNull(object obj, string paramName) throw new ArgumentNullException(paramName, $"Parameter is null."); } } + + private static void ValidateModel(Feature feature) + { + //do some validation + } } From b5bcbf83708f710c72d3040cadebbd84efff7793 Mon Sep 17 00:00:00 2001 From: Yaroslav-B <91521756+Yaroslav-B@users.noreply.github.com> Date: Fri, 21 Apr 2023 13:13:12 +0300 Subject: [PATCH 11/11] refactor: extract null-checking of string parameter to separate method --- ManagedCode.FeatureChecker/FeatureChecker.cs | 28 +++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/ManagedCode.FeatureChecker/FeatureChecker.cs b/ManagedCode.FeatureChecker/FeatureChecker.cs index d27da99..40c5b95 100644 --- a/ManagedCode.FeatureChecker/FeatureChecker.cs +++ b/ManagedCode.FeatureChecker/FeatureChecker.cs @@ -36,11 +36,7 @@ public bool TryAddFeature(Feature newFeature) public void RemoveFeature(string name) { - if(string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); - } - + ThrowIfNullOrEmpty(name, nameof(name)); _features.Remove(name); } @@ -49,16 +45,11 @@ public void RemoveFeature(string name) public bool IsFeatureExists(string name) { - if(string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); - } + ThrowIfNullOrEmpty(name, nameof(name)); return _features.ContainsKey(name); } - - public bool TryGetFeatureStatus(string name, out FeatureStatus status) { var result = TryGetFeatureByName(name, out Feature? feature); @@ -67,17 +58,14 @@ public bool TryGetFeatureStatus(string name, out FeatureStatus status) return result; } - public bool TryGetFeatureByName(string name, out Feature? feature) { - if(string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentException($"Invalid parameter '{nameof(name)}': {name}."); - } + ThrowIfNullOrEmpty(name, nameof(name)); return _features.TryGetValue(name, out feature); } + public Feature[] GetExistFeatures() => _features.Values.ToArray(); public IEnumerable GetFeaturesByStatus(FeatureStatus status) @@ -107,6 +95,14 @@ private static void ThrowIfNull(object obj, string paramName) } } + private static void ThrowIfNullOrEmpty(string arg, string argName) + { + if(string.IsNullOrWhiteSpace(arg)) + { + throw new ArgumentException($"Invalid parameter '{argName}': {arg}."); + } + } + private static void ValidateModel(Feature feature) { //do some validation