Example #1
0
 internal PropertyInfoBinding(IControl control,
                              IControlDescriptor ctrlDesc, IList <IControlDescriptor> parents, PropertyInfoMetadata metadata)
     : base(control)
 {
     ControlDescriptor = ctrlDesc;
     m_Parents         = parents;
     m_Metadata        = metadata;
 }
        private void TraverseType <TDataModel>(Type type, List <IControlDescriptor> parents,
                                               CreateBindingControlDelegate ctrlCreator, CreateDynamicControlsDelegate dynCtrlDescCreator,
                                               IGroup parentCtrl, IReadOnlyDictionary <object, PropertyInfoMetadata> metadata,
                                               List <IBinding> bindings, IRawDependencyGroup dependencies, ref int nextCtrlId)
        {
            foreach (var prp in type.GetProperties())
            {
                IControlDescriptor[] ctrlDescriptors;

                var dynCtrlAtt = prp.GetCustomAttribute <DynamicControlsAttribute>();

                if (dynCtrlAtt != null)
                {
                    if (dynCtrlDescCreator != null)
                    {
                        ctrlDescriptors = dynCtrlDescCreator.Invoke(dynCtrlAtt.Tag) ?? new IControlDescriptor[0];
                    }
                    else
                    {
                        throw new DynamicControlHandlerMissingException(prp);
                    }

                    ctrlDescriptors = ctrlDescriptors.Select(d => new ControlDescriptorWrapper(d, prp)).ToArray();
                }
                else
                {
                    ctrlDescriptors = new IControlDescriptor[]
                    {
                        new PropertyInfoControlDescriptor(prp)
                    };
                }

                foreach (var ctrlDesc in ctrlDescriptors)
                {
                    var prpType = ctrlDesc.DataType;

                    var atts = GetAttributeSet(ctrlDesc, nextCtrlId);

                    if (!atts.Has <IIgnoreBindingAttribute>() && !atts.Has <IMetadataAttribute>())
                    {
                        PropertyInfoMetadata prpMetadata = null;

                        if (atts.Has <IHasMetadataAttribute>())
                        {
                            var metadataTag = atts.Get <IHasMetadataAttribute>().MetadataTag;

                            if (metadataTag != null)
                            {
                                if (!metadata.TryGetValue(metadataTag, out prpMetadata))
                                {
                                    throw new MissingMetadataException(metadataTag, ctrlDesc);
                                }
                            }
                        }

                        int idRange;
                        var ctrl = ctrlCreator.Invoke(prpType, atts, parentCtrl, prpMetadata, out idRange);
                        nextCtrlId += idRange;

                        var binding = new PropertyInfoBinding <TDataModel>(ctrl, ctrlDesc, parents, prpMetadata);
                        bindings.Add(binding);

                        if (atts.Has <IControlTagAttribute>())
                        {
                            var tag = atts.Get <IControlTagAttribute>().Tag;
                            dependencies.RegisterBindingTag(binding, tag);
                        }

                        if (atts.Has <IDependentOnAttribute>())
                        {
                            foreach (var depAtt in atts.GetAll <IDependentOnAttribute>())
                            {
                                if (depAtt.Dependencies?.Any() == true)
                                {
                                    dependencies.RegisterDependency(binding,
                                                                    depAtt.Dependencies, depAtt.DependencyHandler);
                                }
                            }
                        }

                        if (atts.Has <IDependentOnMetadataAttribute>())
                        {
                            var depAtt = atts.Get <IDependentOnMetadataAttribute>();

                            var depMds = depAtt.Dependencies.Select(t =>
                            {
                                if (!metadata.TryGetValue(t, out PropertyInfoMetadata md))
                                {
                                    throw new MissingMetadataException(t, ctrlDesc);
                                }

                                return(md);
                            }).ToArray();

                            dependencies.RegisterMetadataDependency(ctrl, depMds, depAtt.DependencyHandler);
                        }

                        var isGroup = ctrl is IGroup;

                        if (isGroup)
                        {
                            var grpParents = new List <IControlDescriptor>(parents);
                            grpParents.Add(ctrlDesc);
                            TraverseType <TDataModel>(prpType, grpParents, ctrlCreator, dynCtrlDescCreator,
                                                      ctrl as IGroup, metadata, bindings, dependencies, ref nextCtrlId);
                        }
                    }
                }
            }
        }