private void Build(string projection, Type type, IList sourceList)
            {
                // TODO: Static registry!
                // TODO: Ovveride value ranges.

                string[] parts = projection.Split(new[] { '.' });
                var accessorList = new List<IPropertyOrFieldAccessor>(parts.Length);
                Type currentType = type;
                char? postfix = null;
                for (int idx = 0; idx < parts.Length; idx++)
                {
                    string part = parts[idx];

                    if (string.IsNullOrEmpty(part))
                    {
                        throw GetPartNotFoundEx(projection);
                    }

                    if (idx == parts.Length - 1)
                    {
                        part = FeatureHelpers.GetID(part, out postfix);
                    }

                    if (string.IsNullOrEmpty(part))
                    {
                        throw GetPartNotFoundEx(projection);
                    }

                    IPropertyOrFieldAccessor cacc;
                    try
                    {
                        MemberInfo cmi = currentType.GetProperty(part);
                        cacc = AccessorFactory.CreatePropertyOrFieldAccessor(cmi);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException(
                            string.Format("Property '{0}' not found or cannot be accessed on type '{1}'. See inner exception for details.", part, currentType.Name), ex);
                    }

                    accessorList.Add(cacc);
                    currentType = cacc.PropertyOrFieldType;
                }

                // Ok. Accessors found.
                accessors = accessorList.ToArray();
                Debug.Assert(accessors.Length > 0);

                // Create Description:
                char? foo;
                string id = FeatureHelpers.GetID(projection, out foo);
                try
                {
                    switch (postfix)
                    {
                        case '<':
                        case '>':
                            Description = new SetFeatureDescription(id, postfix == '>', GetDistinctValues(sourceList, id));
                            break;
                        case '#':
                            Description = CreateBinaryFeatureDescription(id, sourceList);
                            break;
                        default:
                            Description = new ValueFeatureDescription(id, GetMinMaxRange(sourceList, id)); 
                            break;
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException(
                            string.Format("Cannot initialize feature description by id '{0}'. See inner exception for details.", id), ex);
                }

                // Done.
            }
Example #2
0
 internal ValueFeature(ValueFeatureDescription description, double? value)
     : base(description, value != null ? description.OriginalValueRange.Cut(value.Value) : value)
 {
     Contract.Requires(description != null);
 }