using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using CTA.FeatureDetection.Common.Exceptions; using CTA.FeatureDetection.Common.Models.Configuration; using CTA.FeatureDetection.Common.Models.Enums; using CTA.FeatureDetection.Common.Models.Features.Conditions.Base; [assembly: InternalsVisibleTo("CTA.FeatureDetection.Tests")] namespace CTA.FeatureDetection.Load.Factories { internal class ConditionFactory { /// /// Get instance of a condition from condition metadata /// /// Metadata specifying the type of condition to instantiate and its property values /// Condition instance public static Condition GetCondition(ConditionMetadata conditionMetadata) { var assembly = Assembly.GetAssembly(typeof(Condition)); var className = ConditionTypeEnumToClassName(conditionMetadata.Type); var conditionType = assembly.GetTypes().SingleOrDefault(t => t.Name == className); if (conditionType == null) { throw new ClassNotFoundException(assembly, className); } if (!(Activator.CreateInstance(conditionType, conditionMetadata) is Condition conditionInstance)) { throw new InvalidCastException($"Type {className} cannot be cast to {typeof(Condition)}"); } return conditionInstance; } /// /// Get a collection of condition instances from condition metadata /// /// Collection of metadata specifying the types of conditions to instantiate and their properties' values /// Collection of condition instances public static IEnumerable GetConditions(IEnumerable conditionsMetadata) { return conditionsMetadata.Select(GetCondition); } private static string ConditionTypeEnumToClassName(ConditionType conditionType) { return $"{conditionType}Condition"; } } }