public static BindingDefinitionComposite CreateInstance(Type type, BindingDefinitionDescription definitionDescription) { try { if (string.IsNullOrEmpty(definitionDescription.Name)) { definitionDescription.Name = definitionDescription.BindingExpression.Replace('.', '_'); MatchCollection ret = ValidCharExtract.Matches(definitionDescription.Name); StringBuilder sb = new StringBuilder(); foreach (Match m in ret) { sb.Append(m.Value); } definitionDescription.Name = sb.ToString(); } definitionDescription.BindingExpression = definitionDescription.BindingExpression.Substring(1); definitionDescription.BindingExpression = definitionDescription.BindingExpression.Substring(0, definitionDescription.BindingExpression.Length - 1); BindingDefinitionComposite definition = null; string bindingFormat = definitionDescription.BindingExpression; List <string> results = new List <string>(); MatchCollection matches = Regex.Matches(bindingFormat, pattern); int cpt = -1; foreach (Match match in matches) { string[] elements = match.Value.Split(new[] { "::" }, StringSplitOptions.None); if (string.IsNullOrEmpty(elements[0])) { bindingFormat = bindingFormat.Replace($"{{{match.Value}}}", string.Empty); } else { int pos = results.FindIndex(s => s.Equals(elements[0])); if (pos == -1) { results.Add(elements[0]); pos = ++cpt; } else { pos = cpt; } string format = $"{{{match.Value}}}"; bindingFormat = bindingFormat.Replace(format, $"{{{pos}}}"); } } if (results.Count > 0) { List <BindingDefinitionDescription> definitionDescriptions = new List <BindingDefinitionDescription>(); if (results.Count == 1) { definitionDescriptions.Add(new BindingDefinitionDescription() { BindingExpression = results[0], IsReadOnly = definitionDescription.IsReadOnly }); } else { definitionDescriptions.AddRange(results.Select(s => new BindingDefinitionDescription() { BindingExpression = s, IsReadOnly = true })); } List <IBindingDefinition> nestedDefinitions = BindingDefinitionFactory.CreateInstances(type, definitionDescriptions); if (nestedDefinitions.FirstOrDefault(nd => nd.IsACollection) != null) { throw new BindingTemplateException("The nested 'BindingDefinition' of a 'Composite BindingDefinition' cannot be a collection"); } // If more than one nested definition, then force the Binding definition to be ReadOnly definitionDescription.IsReadOnly = nestedDefinitions.Count > 1 || nestedDefinitions[0].IsReadOnly; definition = new BindingDefinitionComposite(definitionDescription) { nestedDefinitions = nestedDefinitions, BindingFormat = bindingFormat, BindingType = typeof(string) }; definition.canBeNotifiedNestedDefinitions = definition.nestedDefinitions.Where(d => d.CanNotify).ToList(); definition.CanNotify = definition.canBeNotifiedNestedDefinitions.Count > 0; } return(definition); } catch (Exception ex) { throw new BindingTemplateException($"Cannot create the 'Composite BindingDefinition' '{definitionDescription.BindingExpression}'. {ex.Message}"); } }
/// <summary> Create a binding definition for a given <see cref="BindingDefinitionDescription"/> of a given <see cref="Type"/> </summary> /// <param name="sourceType">The Type on which the '<see cref="BindingDefinitionDescription"/>' is based</param> /// <param name="definitionDescription">The given <see cref="Type"/></param> /// <returns>The newly created Binding definition or an exception is an error occurs</returns> internal static IBindingDefinition CreateInstance(Type sourceType, BindingDefinitionDescription definitionDescription) { if (string.IsNullOrEmpty(definitionDescription?.BindingExpression)) { return(null); } try { /// Optional //////////// if (sourceType == null) { return(BindingDefinitionOptional.CreateInstance(definitionDescription)); } /// Composite ///////////// if (definitionDescription.BindingExpression.StartsWith("{") && definitionDescription.BindingExpression.EndsWith("}")) { return(BindingDefinitionComposite.CreateInstance(sourceType, definitionDescription)); } /// Hierarchical //////////////// if (definitionDescription.BindingExpression.Contains(".")) { return(BindingDefinitionHierarchical.CreateInstance(sourceType, definitionDescription)); } //// keyword //////////// //if (definition == null && BindingDefinitionKeyWord.KeyWords.Contains(bindingName)) // definition = BindingDefinitionKeyWord.CreateInstances(bindingName); /// Properties ////////////// List <PropertyInfo> propertyInfos = (from pi in sourceType.GetProperties() where pi.Name.Equals(definitionDescription.BindingExpression) && pi.GetGetMethod() != null && pi.GetGetMethod().IsPublic select pi).ToList(); if (propertyInfos != null && propertyInfos.Count > 0) { PropertyInfo propertyInfo; if (propertyInfos.Count == 1) { propertyInfo = propertyInfos[0]; } else // To take the keuword 'new' into account { propertyInfo = propertyInfos.FirstOrDefault(pi => { MethodInfo mi = pi.GetGetMethod(); bool isNew = (mi.Attributes & MethodAttributes.HideBySig) == MethodAttributes.HideBySig && mi.DeclaringType.Equals(sourceType); return(isNew); }); } return(BindingDefinitionProperty.CreateInstance(propertyInfo, definitionDescription)); } /// Fields ////////// FieldInfo fieldInfo = sourceType.GetFields().FirstOrDefault(fi => fi.Name.Equals(definitionDescription.BindingExpression) && fi.IsPublic); if (fieldInfo != null) { return(BindingDefinitionField.CreateInstance(fieldInfo, definitionDescription)); } /// Methods /////////// MethodInfo methodInfo = sourceType.GetMethods().FirstOrDefault(mi => mi.Name.Equals(definitionDescription.BindingExpression) && mi.IsPublic); if (methodInfo != null) { return(BindingDefinitionMethod.CreateInstance(methodInfo)); } return(BindingDefinitionOptional.CreateInstance(definitionDescription)); } catch (Exception ex) { throw new BindingTemplateException($"Cannot create 'BindingDefinition' between '{sourceType.Name}' and '{definitionDescription.BindingExpression}'", ex); } }