Esempio n. 1
0
        private void TraverseType <TDataModel>(Type type, List <PropertyInfo> parents,
                                               CreateBindingControlDelegate ctrlCreator,
                                               IGroup parentCtrl, List <IBinding> bindings, IRawDependencyGroup dependencies, ref int nextCtrlId)
        {
            foreach (var prp in type.GetProperties())
            {
                var prpType = prp.PropertyType;

                var atts = GetAttributeSet(prp, nextCtrlId);

                if (!atts.Has <IIgnoreBindingAttribute>())
                {
                    int idRange;
                    var ctrl = ctrlCreator.Invoke(prpType, atts, parentCtrl, out idRange);
                    nextCtrlId += idRange;

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

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

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

                        if (depAtt.Dependencies?.Any() == true)
                        {
                            dependencies.RegisterDependency(binding,
                                                            depAtt.Dependencies, depAtt.DependencyHandler);
                        }
                    }

                    var isGroup = ctrl is IGroup;

                    if (isGroup)
                    {
                        var grpParents = new List <PropertyInfo>(parents);
                        grpParents.Add(prp);
                        TraverseType <TDataModel>(prpType, grpParents, ctrlCreator,
                                                  ctrl as IGroup, bindings, dependencies, ref nextCtrlId);
                    }
                }
            }
        }
Esempio n. 2
0
        private void TraverseType <TDataModel>(Type type, List <IControlDescriptor> parents,
                                               CreateBindingControlDelegate ctrlCreator, CreateDynamicControlsDelegate dynCtrlDescCreator,
                                               IGroup parentCtrl, IReadOnlyDictionary <object, PropertyInfoMetadata> metadata,
                                               List <IBinding> bindings, IRawDependencyGroup dependencies, IContextProvider contextProvider, ref int nextCtrlId)
        {
            foreach (var prp in type.GetProperties().OrderBy(p =>
            {
                var orderAtt = p.GetCustomAttribute <OrderAttribute>();

                if (orderAtt != null)
                {
                    return(orderAtt.Order);
                }
                else
                {
                    return(0);
                }
            }))
            {
                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>())
                    {
                        var prpMetadata = new List <PropertyInfoMetadata>();

                        if (atts.Has <IHasMetadataAttribute>())
                        {
                            var metadataTagsAtts = atts.GetAll <IHasMetadataAttribute>();

                            foreach (var metadataTagAtts in metadataTagsAtts)
                            {
                                if (metadataTagAtts.HasMetadata)
                                {
                                    var metadataTag = metadataTagAtts.MetadataTag;

                                    if (metadataTag == null)
                                    {
                                        throw new NullReferenceException($"Metadata tag is not set for {ctrlDesc.Name}");
                                    }

                                    if (metadata.TryGetValue(metadataTag, out PropertyInfoMetadata md))
                                    {
                                        prpMetadata.Add(md);
                                    }
                                    else
                                    {
                                        throw new MissingMetadataException(metadataTag, ctrlDesc);
                                    }
                                }
                            }
                        }

                        var prpMetadataArr = prpMetadata.ToArray();

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

                        var binding = new PropertyInfoBinding <TDataModel>(ctrl, ctrlDesc, parents, prpMetadataArr, contextProvider);
                        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, contextProvider, ref nextCtrlId);
                        }
                    }
                }
            }
        }