void SetUp()
 {
     environmentService = new EnvironmentService(new[] { new ExampleEnvironmentProvider() });
     var policies = new Dictionary<string, IPolicy>
         {
             { "A", new AlphaPolicy() }, 
             { "B", new BetaPolicy() }, 
             { "C", new AlphaPolicy() }, 
             { "D", new AlphaPolicy() }, 
             { "E", new CappaPolicy { MatchUserId = new Guid("880A00AD-5C40-447B-821A-2679E757B267")} }, 
             { "F", new CappaPolicy { MatchUserId = new Guid("1E9A7C0C-FC86-4516-BA42-F7232E65A12C")} }, 
             { "G", new DeltaPolicy() }, 
             { "H", new DeltaPolicy() }
         };
     policyService = new PolicyService(new[] { new PolicyProvider(policies) }, environmentService);
     target = new DecisionService(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test-Decisions.config"), policyService);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="DecisionService" /> class.
        /// </summary>
        /// <param name="configPath">The config path.</param>
        /// <param name="service">The service.</param>
        public DecisionService(string configPath, PolicyService service)
        {
            var settings = XElement.Load(Path.GetFullPath(configPath));

            // Validate the XML Formatting to prevent bad errors being thrown which have poor debugging information due to their nature
            if (settings.Elements("namespace").Any() == false) throw new ConfigurationMalformedException("No namespace elements could be found.");

            foreach (var expressionSection in settings.Elements("namespace"))
            {
                if (expressionSection.HasAttributes == false || expressionSection.Attributes().Any(a => a.Name == "name") == false)
                {
                    throw new ConfigurationMalformedException("One of the namespace elements does not have a name attribute.");
                }

                var component = expressionSection.Attribute("name").Value;
                var expressionProvider = new ExpressionProvider(expressionSection.Element("decisions"), service);
                providers.AddOrUpdate(component, expressionProvider, (key, oldValue) => expressionProvider);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ExpressionProvider" /> class.
        /// </summary>
        /// <param name="settings">The settings.</param>
        /// <param name="provider">The provider.</param>
        /// <exception cref="System.Configuration.ConfigurationErrorsException">All expressions must specify a unique 'key'.
        /// or
        /// All expressions must specify a 'value'.</exception>
        /// <exception cref="ConfigurationErrorsException">All expressions must specify a unique 'key'.
        /// or
        /// All expressions must specify a 'value'.</exception>
        public ExpressionProvider(XElement settings, PolicyService provider)
        {
            expressions = new Dictionary<string, string>();
            this.provider = provider;

            // Validate the XML Formatting to prevent bad errors being thrown which have poor debugging information due to their nature
            if (settings == null || settings.Name.LocalName.Equals("decisions") == false)
            {
                throw new ConfigurationMalformedException("No decisions elements could be found.");
            }

            if (settings.Elements("item").Any() == false)
            {
                throw new ConfigurationMalformedException("No item elements could be found.");
            }

            foreach (var item in settings.Elements("item"))
            {
                if (item.HasAttributes == false || item.Attributes().Any(a => a.Name == "key") == false)
                {
                    throw new ConfigurationMalformedException("One of the item elements does not have a key attribute.");
                }

                if (item.Attributes().Any(a => a.Name == "value") == false)
                {
                    throw new ConfigurationMalformedException("One of the item elements does not have a value attribute.");
                }

                var key = item.Attribute("key");
                if (key == null || string.IsNullOrWhiteSpace((string)key))
                {
                    throw new ArgumentException("All expressions must specify a unique 'key'.", key.ToString());
                }

                var value = item.Attribute("value");
                if (value == null || string.IsNullOrWhiteSpace((string)value))
                {
                    throw new ArgumentException("All expressions must specify a 'value'.", value.ToString());
                }

                expressions[(string)key] = Reduce((string)value);
            }
        }