From 208a020fbddb6efacf03d5a1092c3ecc4e052b53 Mon Sep 17 00:00:00 2001 From: Joonas Griesinger Date: Tue, 13 Dec 2022 15:43:31 +0100 Subject: [PATCH 1/4] Extract condition collection code into separate class. --- src/Conditions/ConditionCollection.cs | 143 ++++++++++++++++++++++++++ src/RatingGateway.cs | 119 ++------------------- 2 files changed, 153 insertions(+), 109 deletions(-) create mode 100644 src/Conditions/ConditionCollection.cs diff --git a/src/Conditions/ConditionCollection.cs b/src/Conditions/ConditionCollection.cs new file mode 100644 index 0000000..090fbdb --- /dev/null +++ b/src/Conditions/ConditionCollection.cs @@ -0,0 +1,143 @@ +using System.Collections.Generic; +using System.Linq; +using Griesoft.Xamarin.RatingGateway.Cache; + +namespace Griesoft.Xamarin.RatingGateway.Conditions +{ + /// + /// A collection class for 's. + /// + public class ConditionCollection + { + private readonly Dictionary _conditions; + + /// + /// + /// + public ConditionCollection() + { + _conditions = new Dictionary(); + RatingConditionCache = new DefaultRatingConditionCache(); + } + + /// + /// + /// + /// + /// + public IRatingCondition this[string key] => _conditions[key]; + + /// + /// The rating condition cache that does manage the reading and writing of cached values to the file system. + /// + public IRatingConditionCache RatingConditionCache { get; set; } + + /// + /// The condition collection returned as an enumerable. + /// + public IEnumerable> RatingConditions => _conditions.AsEnumerable(); + + /// + /// True if the condition collection contains any condition that is of type . + /// + public bool HasPrerequisiteConditions => _conditions.Any(condition => condition.Value.ConditionType == ConditionType.Prerequisite); + + /// + /// True if the condition collection contains any condition that is of type . + /// + public bool HasRequiredConditions => _conditions.Any(condition => condition.Value.ConditionType == ConditionType.Requirement); + + /// + /// True if the condition collection contains only conditions that are of type . + /// + /// + /// Make sure that this always returns false. If it doesn't, the rating gateway will never prompt the user to review your application. + /// + public bool HasOnlyPrerequisiteConditions => _conditions.Count > 0 && _conditions.All(condition => condition.Value.ConditionType == ConditionType.Prerequisite); + + + /// + /// Add a condition to the collection. + /// + /// The unique name of the condition. + /// The condition instance that will be added to the collection. + /// Thrown if a condition with the given name already exists in the collection. + public virtual void AddCondition(string conditionName, IRatingCondition condition) + { + _conditions.Add(conditionName, condition); + + if (condition is ICachableCondition cachableCondition && cachableCondition.CacheCurrentValue) + { + if (!RatingConditionCache.Load(conditionName, cachableCondition)) + { + RatingConditionCache.Save(conditionName, cachableCondition); + } + } + } + + /// + /// Add multiple conditions to the collection at once. + /// + /// A collection of key-value pairs where the key is used as the unique condition name and the value is added to the condition collection. + /// Thrown if a condition with the given name already exists in the collection. + public virtual void AddCondition(IEnumerable> conditions) + { + foreach (var condition in conditions) + { + AddCondition(condition.Key, condition.Value); + } + } + + /// + /// Remove a condition with the specified name from the collection if it exists. + /// + /// The unique name of the condition. + /// If true a cached state of the condition will also be removed from the cache. By default true. + public virtual void RemoveCondition(string conditionName, bool removeFromCache = true) + { + _conditions.Remove(conditionName); + + if (removeFromCache) + { + RatingConditionCache.Delete(conditionName); + } + } + + /// + /// Reset all condition states in the collection. + /// + public virtual void ResetAllConditions() + { + foreach (var condition in _conditions) + { + condition.Value.Reset(); + + SaveCachableConditionState(condition.Key, condition.Value); + } + } + + /// + /// Check whether the collections contains the or not. + /// + /// + /// true if the collections contains the key, otherwise false. + public virtual bool ContainsKey(string key) + { + return _conditions.ContainsKey(key); + } + + + /// + /// + /// + /// + /// + protected void SaveCachableConditionState(string conditionName, IRatingCondition condition) + { + if (condition is ICachableCondition cachableCondition && cachableCondition.CacheCurrentValue) + { + RatingConditionCache.Save(conditionName, cachableCondition); + } + } + } +} diff --git a/src/RatingGateway.cs b/src/RatingGateway.cs index eb95cd4..6aa6134 100644 --- a/src/RatingGateway.cs +++ b/src/RatingGateway.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; +using Griesoft.Xamarin.RatingGateway.Abstractions; using Griesoft.Xamarin.RatingGateway.Cache; using Griesoft.Xamarin.RatingGateway.Conditions; @@ -19,53 +20,20 @@ namespace Griesoft.Xamarin.RatingGateway /// Each time a rating action is triggered the gateway will manipulate conditions by given factors, evaluate through them to check if all necessary conditions are met, /// reset met conditions if allowed, and cache the current state of cachable conditions. /// - public class RatingGateway + public class RatingGateway : ConditionCollection { - private readonly Dictionary _ratingConditions; - - internal RatingGateway() + internal RatingGateway() : base() { - _ratingConditions = new Dictionary(); - RatingView = new DefaultRatingView(); - RatingConditionCache = new DefaultRatingConditionCache(); } private bool IsInitialized { get; set; } = false; - /// - /// The condition collection returned as an enumerable. - /// - public IEnumerable> RatingConditions => _ratingConditions.AsEnumerable(); - - /// - /// True if the condition collection contains any condition that is of type . - /// - public bool HasPrerequisiteConditions => _ratingConditions.Any(condition => condition.Value.ConditionType == ConditionType.Prerequisite); - - /// - /// True if the condition collection contains any condition that is of type . - /// - public bool HasRequiredConditions => _ratingConditions.Any(condition => condition.Value.ConditionType == ConditionType.Requirement); - - /// - /// True if the condition collection contains only conditions that are of type . - /// - /// - /// Make sure that this always returns false. If it doesn't, the rating gateway will never prompt the user to review your application. - /// - public bool HasOnlyPrerequisiteConditions => _ratingConditions.Count > 0 && _ratingConditions.All(condition => condition.Value.ConditionType == ConditionType.Prerequisite); - /// /// The rating view that does display the rating page to the user. /// public IRatingView RatingView { get; set; } - /// - /// The rating condition cache that does manage the reading and writing of cached values to the file system. - /// - public IRatingConditionCache RatingConditionCache { get; set; } - /// /// A singleton instance of the rating gateway. /// @@ -130,66 +98,6 @@ public static void Initialize(IEnumerable } } - /// - /// Add a condition to the collection. - /// - /// The unique name of the condition. - /// The condition instance that will be added to the collection. - /// Thrown if a condition with the given name already exists in the collection. - public void AddCondition(string conditionName, IRatingCondition condition) - { - _ratingConditions.Add(conditionName, condition); - - if (condition is ICachableCondition cachableCondition && cachableCondition.CacheCurrentValue) - { - if (!RatingConditionCache.Load(conditionName, cachableCondition)) - { - RatingConditionCache.Save(conditionName, cachableCondition); - } - } - } - - /// - /// Add multiple conditions to the collection at once. - /// - /// A collection of key-value pairs where the key is used as the unique condition name and the value is added to the condition collection. - /// Thrown if a condition with the given name already exists in the collection. - public void AddCondition(IEnumerable> conditions) - { - foreach(var condition in conditions) - { - AddCondition(condition.Key, condition.Value); - } - } - - /// - /// Remove a condition with the specified name from the collection if it exists. - /// - /// The unique name of the condition. - /// If true a cached state of the condition will also be removed from the cache. By default true. - public void RemoveCondition(string conditionName, bool removeFromCache = true) - { - _ratingConditions.Remove(conditionName); - - if (removeFromCache) - { - RatingConditionCache.Delete(conditionName); - } - } - - /// - /// Reset all condition states in the collection. - /// - public void ResetAllConditions() - { - foreach(var condition in _ratingConditions) - { - condition.Value.Reset(); - - SaveCachableConditionState(condition.Key, condition.Value); - } - } - /// /// Evaluate through all conditions in the collection and if all necessary conditions are met open the rating page. /// @@ -346,7 +254,7 @@ public async Task EvaluateAsync(Dictionary parameters, bool man private void ResetAllMetConditions(bool evaluationResult) { - foreach(var condition in _ratingConditions.Where(con => con.Value.ResetAfterConditionMet && con.Value.IsConditionMet)) + foreach(var condition in RatingConditions.Where(con => con.Value.ResetAfterConditionMet && con.Value.IsConditionMet)) { if (condition.Value.ResetOnlyOnEvaluationSuccess && !evaluationResult) { @@ -360,7 +268,7 @@ private void ResetAllMetConditions(bool evaluationResult) } private void ManipulateConditionState(Dictionary? parameters) { - foreach(var condition in _ratingConditions) + foreach(var condition in RatingConditions) { var containsKey = parameters?.ContainsKey(condition.Key) ?? false; var conditionParam = containsKey ? parameters?[condition.Key] : null; @@ -385,7 +293,7 @@ private bool EvaluateConditions(IEnumerable? priorityConditions = defaul { // Make sure all prerequisite conditions are met before proceeding if (HasOnlyPrerequisiteConditions || - !_ratingConditions.Where(condition => condition.Value.ConditionType == ConditionType.Prerequisite) + !RatingConditions.Where(condition => condition.Value.ConditionType == ConditionType.Prerequisite) .All(condition => condition.Value.IsConditionMet)) { return false; @@ -394,7 +302,7 @@ private bool EvaluateConditions(IEnumerable? priorityConditions = defaul var hasPriorConditions = priorityConditions != null && priorityConditions.Count() > 0; // Make sure all required conditions are met before proceeding - if (!_ratingConditions.Where(condition => condition.Value.ConditionType == ConditionType.Requirement) + if (!RatingConditions.Where(condition => condition.Value.ConditionType == ConditionType.Requirement) .All(condition => condition.Value.IsConditionMet)) { return false; @@ -409,21 +317,14 @@ private bool EvaluateConditions(IEnumerable? priorityConditions = defaul // Check that the condition of all specified conditions is met if we have any specified. if (hasPriorConditions) { - return priorityConditions.All(conditionName => _ratingConditions.ContainsKey(conditionName) - ? _ratingConditions[conditionName].IsConditionMet + return priorityConditions.All(conditionName => ContainsKey(conditionName) + ? this[conditionName].IsConditionMet : false); } // No condition was prioritized, so it is enough for any standard condition to be true - return _ratingConditions.Any(condition => condition.Value.ConditionType == ConditionType.Standard && + return RatingConditions.Any(condition => condition.Value.ConditionType == ConditionType.Standard && condition.Value.IsConditionMet); } - private void SaveCachableConditionState(string conditionName, IRatingCondition condition) - { - if (condition is ICachableCondition cachableCondition && cachableCondition.CacheCurrentValue) - { - RatingConditionCache.Save(conditionName, cachableCondition); - } - } } } From 0e326584d42e2c81c4573ea9384d121ef85ead98 Mon Sep 17 00:00:00 2001 From: Joonas Griesinger Date: Tue, 13 Dec 2022 15:47:59 +0100 Subject: [PATCH 2/4] Fixing build issue. --- src/RatingGateway.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/RatingGateway.cs b/src/RatingGateway.cs index 6aa6134..e81c6a3 100644 --- a/src/RatingGateway.cs +++ b/src/RatingGateway.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; -using Griesoft.Xamarin.RatingGateway.Abstractions; using Griesoft.Xamarin.RatingGateway.Cache; using Griesoft.Xamarin.RatingGateway.Conditions; From a54f7d4e9c19a38c50a1c218bdbc33a465945b46 Mon Sep 17 00:00:00 2001 From: Joonas Griesinger Date: Tue, 13 Dec 2022 15:48:31 +0100 Subject: [PATCH 3/4] Update dependencies to latest stable versions. --- src/RatingGateway.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RatingGateway.csproj b/src/RatingGateway.csproj index 3251327..dad4d9d 100644 --- a/src/RatingGateway.csproj +++ b/src/RatingGateway.csproj @@ -37,7 +37,7 @@ - + From 6de22ed28f9408c002a31ea11fd71da47b12d180 Mon Sep 17 00:00:00 2001 From: Joonas Griesinger Date: Tue, 13 Dec 2022 15:50:28 +0100 Subject: [PATCH 4/4] Updating documentation. --- docs/Griesoft.Xamarin.RatingGateway.xml | 239 +++++++++++++----------- 1 file changed, 135 insertions(+), 104 deletions(-) diff --git a/docs/Griesoft.Xamarin.RatingGateway.xml b/docs/Griesoft.Xamarin.RatingGateway.xml index ff37ad7..95c31f3 100644 --- a/docs/Griesoft.Xamarin.RatingGateway.xml +++ b/docs/Griesoft.Xamarin.RatingGateway.xml @@ -146,98 +146,91 @@ Inverts the current state of this condition. - + - A count condition that by default evaluates to true when the current count has reached the specified goal. Use it to keep count of user events in your application or as a countdown. + A collection class for 's. - + - Specify the initial count for this condition. - Specify the count goal for this condition. When the current state is equal of exceeds that goal the condition is met. - + - Specify the initial count for this condition. - Specify the count goal for this condition. When the current state is equal of exceeds that goal the condition is met. - Specify the condition type. + + - + - + The rating condition cache that does manage the reading and writing of cached values to the file system. - Specify the initial count for this condition. - An evaluator function that determines when the condition is met. - + - + The condition collection returned as an enumerable. - Specify the initial count for this condition. - An evaluator function that determines when the condition is met. - Specify the condition type. - + - Increase the current count of this condition by one. + True if the condition collection contains any condition that is of type . - + - A condition that will evaluate to true after a specific moment in time is in the past. - Use it to wait for a certain amount of time before asking the user to review your application, for example. + True if the condition collection contains any condition that is of type . + + + + + True if the condition collection contains only conditions that are of type . - By caching the current state of this condition, the loading process of cached values will set the current state to the same - state that it was when the condition was added the first time. + Make sure that this always returns false. If it doesn't, the rating gateway will never prompt the user to review your application. - + - + Add a condition to the collection. - The amount of time to add to when setting the initial state of this condition. + The unique name of the condition. + The condition instance that will be added to the collection. + Thrown if a condition with the given name already exists in the collection. - + - + Add multiple conditions to the collection at once. - The amount of time to add to when setting the initial state of this condition. - Specify the condition type. + A collection of key-value pairs where the key is used as the unique condition name and the value is added to the condition collection. + Thrown if a condition with the given name already exists in the collection. - + - Reset will add the amount of time that was passed to the constructor of this condition to and set the result as current state. + Remove a condition with the specified name from the collection if it exists. + The unique name of the condition. + If true a cached state of the condition will also be removed from the cache. By default true. - + - A generic condition that enables you to create custom conditions with minimal effort. + Reset all condition states in the collection. - - If you need custom manipulation or reset logic, or if you want to add more complex functionality that the build-in conditions don't provide, - you should write a custom condition and inherit from the condition base class . - - - + - + Check whether the collections contains the or not. - Specify the initial value for this condition. - An evaluator function that determines when the condition is met. + + true if the collections contains the key, otherwise false. - + - Specify the initial value for this condition. - An evaluator function that determines when the condition is met. - Specify the condition type. + + @@ -374,6 +367,99 @@ The value to use for state manipulation. + + + A count condition that by default evaluates to true when the current count has reached the specified goal. Use it to keep count of user events in your application or as a countdown. + + + + + + + Specify the initial count for this condition. + Specify the count goal for this condition. When the current state is equal of exceeds that goal the condition is met. + + + + + + Specify the initial count for this condition. + Specify the count goal for this condition. When the current state is equal of exceeds that goal the condition is met. + Specify the condition type. + + + + + + Specify the initial count for this condition. + An evaluator function that determines when the condition is met. + + + + + + Specify the initial count for this condition. + An evaluator function that determines when the condition is met. + Specify the condition type. + + + + Increase the current count of this condition by one. + + + + + A condition that will evaluate to true after a specific moment in time is in the past. + Use it to wait for a certain amount of time before asking the user to review your application, for example. + + + By caching the current state of this condition, the loading process of cached values will set the current state to the same + state that it was when the condition was added the first time. + + + + + + + The amount of time to add to when setting the initial state of this condition. + + + + + + The amount of time to add to when setting the initial state of this condition. + Specify the condition type. + + + + Reset will add the amount of time that was passed to the constructor of this condition to and set the result as current state. + + + + + A generic condition that enables you to create custom conditions with minimal effort. + + + If you need custom manipulation or reset logic, or if you want to add more complex functionality that the build-in conditions don't provide, + you should write a custom condition and inherit from the condition base class . + + + + + + + + Specify the initial value for this condition. + An evaluator function that determines when the condition is met. + + + + + + Specify the initial value for this condition. + An evaluator function that determines when the condition is met. + Specify the condition type. + This condition evaluates to true when the current state matches the string that was passed to the constructor as the goal. @@ -520,39 +606,11 @@ reset met conditions if allowed, and cache the current state of cachable conditions. - - - The condition collection returned as an enumerable. - - - - - True if the condition collection contains any condition that is of type . - - - - - True if the condition collection contains any condition that is of type . - - - - - True if the condition collection contains only conditions that are of type . - - - Make sure that this always returns false. If it doesn't, the rating gateway will never prompt the user to review your application. - - The rating view that does display the rating page to the user. - - - The rating condition cache that does manage the reading and writing of cached values to the file system. - - A singleton instance of the rating gateway. @@ -577,33 +635,6 @@ Optional; pass a custom condition cache. If not specified or null, will be used instead. Call it only once in the lifetime of a . All other calls after the initial one, do just return. - - - Add a condition to the collection. - - The unique name of the condition. - The condition instance that will be added to the collection. - Thrown if a condition with the given name already exists in the collection. - - - - Add multiple conditions to the collection at once. - - A collection of key-value pairs where the key is used as the unique condition name and the value is added to the condition collection. - Thrown if a condition with the given name already exists in the collection. - - - - Remove a condition with the specified name from the collection if it exists. - - The unique name of the condition. - If true a cached state of the condition will also be removed from the cache. By default true. - - - - Reset all condition states in the collection. - - Evaluate through all conditions in the collection and if all necessary conditions are met open the rating page.