public void AddRequiredViewField(SPFieldAttribute field) { CommonHelper.ConfirmNotNull(field, "field"); if (field.IncludeInQuery || field.IncludeInViewFields) { requiredViewFields.Add(field.ListFieldInternalName); AddInterfaceDepenedentField(field); if (this.Parent != null) { this.Parent.AddRequiredViewField(field); } } }
public void AddInterfaceDepenedentField(SPFieldAttribute field) { CommonHelper.ConfirmNotNull(field, "field"); if (IsTwoColumnField(field)) { foreach (SPModelDescriptor d in EnumerableHelper.AncestorsAndSelf(this, v => v.Parent)) { if (!d.fieldAttributes.Contains(field)) { d.hiddenFields.Add(field); } } foreach (SPModelDescriptor d in EnumerableHelper.Descendants(this, v => v.Children)) { if (!d.fieldAttributes.Contains(field)) { d.hiddenFields.Add(field); } } } }
protected void CheckFieldConsistency(SPModelDescriptor other) { foreach (SPFieldAttribute definition in fieldAttributes) { SPFieldAttribute parentDefinition = other.fieldAttributes.FirstOrDefault(v => v.InternalName == definition.InternalName); if (parentDefinition != null) { if (definition.GetType() != parentDefinition.GetType()) { throw new SPModelProvisionException(String.Format("Definition for field '{0}' in content type '{1}' conflicts with parent content type.", definition.InternalName, contentTypeAttribute.Name)); } foreach (PropertyInfo property in definition.GetType().GetProperties()) { object myValue = property.GetValue(definition, null); object paValue = property.GetValue(parentDefinition, null); if (!Object.Equals(myValue, paValue)) { if (property.PropertyType == typeof(SPOption) && (SPOption)myValue == SPOption.Unspecified) { continue; } if (property.PropertyType == typeof(StringCollection)) { StringCollection sourceCollection = (StringCollection)myValue; StringCollection targetCollection = (StringCollection)paValue; if (sourceCollection.Count == targetCollection.Count && !sourceCollection.Cast <string>().Except(targetCollection.Cast <string>()).Any()) { continue; } } throw new SPModelProvisionException(String.Format("Definition for field '{0}' in content type '{1}' conflicts with parent content type.", definition.InternalName, contentTypeAttribute.Name)); } } } } }
internal static Type BuildTypeFromAbstractBaseType(Type baseType) { Random random = new Random(); string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; string randomTypeName = String.Concat(baseType.Name, "__", new String(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray())); TypeBuilder typeBuilder = ModuleBuilder.DefineType(randomTypeName, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, baseType); MethodInfo spModelGetAdapterMethod = typeof(SPModel).GetMethod("get_Adapter", true); MethodInfo spModelGetManagerMethod = typeof(SPModel).GetMethod("get_Manager", true); MethodInfo spModelGetParentCollectionMethod = typeof(SPModel).GetMethod("get_ParentCollection", true); MethodInfo ispModelManagerGetTermStoreMethod = typeof(ISPModelManager).GetMethod("get_TermStore"); foreach (PropertyInfo sourceProperty in baseType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { MethodInfo sourceGetter = sourceProperty.GetGetMethod(true); MethodInfo sourceSetter = sourceProperty.GetSetMethod(true); if ((sourceGetter != null && sourceGetter.IsAbstract) || (sourceSetter != null && sourceSetter.IsAbstract)) { SPModelFieldAssociationCollection association = SPModelFieldAssociationCollection.GetByMember(sourceProperty); if (!association.Queryable) { continue; } SPFieldAttribute field = association.Fields.First(); MethodInfo getterMethod = null; MethodInfo setterMethod = null; MethodInfo postGetterMethod = null; MethodInfo preSetterMethod = null; Type secondParameterType = null; if (sourceProperty.PropertyType == typeof(bool)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetBoolean"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetBoolean"); } else if (sourceProperty.PropertyType == typeof(int)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetInteger"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetInteger"); } else if (sourceProperty.PropertyType == typeof(double)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetNumber"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetNumber"); } else if (sourceProperty.PropertyType == typeof(string)) { if (field.Type == SPFieldType.Lookup) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetLookupFieldValue"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetLookupFieldValue"); } else if (field.Type == SPFieldType.URL) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetUrlFieldValue"); setterMethod = typeof(SPExtension).GetMethod("SetUrlFieldValue", new[] { typeof(ISPListItemAdapter), typeof(string), typeof(string) }); postGetterMethod = typeof(SPFieldUrlValue).GetProperty("Url").GetGetMethod(); } else { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetString"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetString"); } } else if (sourceProperty.PropertyType == typeof(Guid)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetGuid"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetGuid"); } else if (sourceProperty.PropertyType == typeof(DateTime?)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetDateTime"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetDateTime"); } else if (sourceProperty.PropertyType == typeof(DateTime)) { getterMethod = typeof(SPExtension).GetMethod("GetDateTimeOrMin"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetDateTime"); preSetterMethod = typeof(DateTime?).GetMethod("op_Implicit"); } else if (sourceProperty.PropertyType == typeof(Term)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetTaxonomy"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetTaxonomy"); secondParameterType = typeof(TermStore); } else if (sourceProperty.PropertyType == typeof(SPFieldUrlValue)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetUrlFieldValue"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetUrlFieldValue"); } else if (sourceProperty.PropertyType == typeof(SPPrincipal)) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetUserFieldValue"); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetUserFieldValue"); } else if (sourceProperty.PropertyType.IsOf <Enum>()) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetEnum").MakeGenericMethod(sourceProperty.PropertyType); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetEnum").MakeGenericMethod(sourceProperty.PropertyType); } else if (sourceProperty.PropertyType.IsOf <SPModel>()) { getterMethod = typeof(ISPListItemAdapter).GetMethod("GetModel").MakeGenericMethod(sourceProperty.PropertyType); setterMethod = typeof(ISPListItemAdapter).GetMethod("SetModel").MakeGenericMethod(sourceProperty.PropertyType); secondParameterType = typeof(SPModelCollection); } else { Type elementType; if (sourceProperty.PropertyType.IsOf(typeof(IEnumerable <>), out elementType)) { bool isReadOnly = sourceProperty.PropertyType.IsOf(typeof(ReadOnlyCollection <>)); if (elementType == typeof(Term)) { getterMethod = typeof(ISPListItemAdapter).GetMethod(isReadOnly ? "GetTaxonomyMultiReadOnly" : "GetTaxonomyMulti"); secondParameterType = typeof(TermStore); } else if (elementType == typeof(SPPrincipal)) { getterMethod = typeof(ISPListItemAdapter).GetMethod(isReadOnly ? "GetMultiUserFieldValueReadOnly" : "GetMultiUserFieldValue"); } else if (elementType == typeof(string)) { if (field.Type == SPFieldType.MultiChoice) { getterMethod = typeof(ISPListItemAdapter).GetMethod(isReadOnly ? "GetMultiChoiceFieldValueReadOnly" : "GetMultiChoiceFieldValue"); } else { getterMethod = typeof(ISPListItemAdapter).GetMethod(isReadOnly ? "GetMultiLookupFieldValueReadOnly" : "GetMultiLookupFieldValue"); } } else { try { SPModelDescriptor.Resolve(elementType); getterMethod = typeof(ISPListItemAdapter).GetMethod(isReadOnly ? "GetModelCollectionReadOnly" : "GetModelCollection").MakeGenericMethod(elementType); secondParameterType = typeof(SPModelCollection); } catch (ArgumentException) { } } if (sourceSetter != null) { throw new InvalidOperationException("Collection property cannot have setter."); } } } if ((sourceGetter != null && getterMethod == null) || (sourceSetter != null && setterMethod == null)) { throw new InvalidOperationException(String.Format("Unable to find suitable method for '{0}.{1}'.", baseType.Name, sourceProperty.Name)); } PropertyBuilder property = typeBuilder.DefineProperty(sourceProperty.Name, PropertyAttributes.HasDefault, sourceProperty.PropertyType, null); if (sourceGetter != null) { MethodBuilder propertyGetter = typeBuilder.DefineMethod(sourceGetter.Name, GetMethodVisibility(sourceGetter) | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig, sourceProperty.PropertyType, Type.EmptyTypes); ILGenerator propertyGetterIL = propertyGetter.GetILGenerator(); propertyGetterIL.Emit(OpCodes.Ldarg_0); propertyGetterIL.Emit(OpCodes.Call, spModelGetAdapterMethod); propertyGetterIL.Emit(OpCodes.Ldstr, field.InternalName); if (secondParameterType != null) { if (secondParameterType == typeof(TermStore)) { propertyGetterIL.Emit(OpCodes.Ldarg_0); propertyGetterIL.Emit(OpCodes.Call, spModelGetManagerMethod); propertyGetterIL.Emit(OpCodes.Callvirt, ispModelManagerGetTermStoreMethod); } else if (secondParameterType == typeof(SPModelCollection)) { propertyGetterIL.Emit(OpCodes.Ldarg_0); propertyGetterIL.Emit(OpCodes.Call, spModelGetParentCollectionMethod); } else { throw new NotSupportedException(); } } if (getterMethod.DeclaringType.IsInterface || getterMethod.IsAbstract) { propertyGetterIL.Emit(OpCodes.Callvirt, getterMethod); } else { propertyGetterIL.Emit(OpCodes.Call, getterMethod); } if (postGetterMethod != null) { propertyGetterIL.Emit(OpCodes.Call, postGetterMethod); } propertyGetterIL.Emit(OpCodes.Ret); property.SetGetMethod(propertyGetter); } if (sourceSetter != null) { MethodBuilder propertySetter = typeBuilder.DefineMethod(sourceSetter.Name, GetMethodVisibility(sourceSetter) | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { sourceProperty.PropertyType }); ILGenerator propertySetterIL = propertySetter.GetILGenerator(); propertySetterIL.Emit(OpCodes.Ldarg_0); propertySetterIL.Emit(OpCodes.Call, spModelGetAdapterMethod); propertySetterIL.Emit(OpCodes.Ldstr, field.InternalName); propertySetterIL.Emit(OpCodes.Ldarg_1); if (preSetterMethod != null) { propertySetterIL.Emit(OpCodes.Call, preSetterMethod); } if (setterMethod.DeclaringType.IsInterface || setterMethod.IsAbstract) { propertySetterIL.Emit(OpCodes.Callvirt, setterMethod); } else { propertySetterIL.Emit(OpCodes.Call, setterMethod); } propertySetterIL.Emit(OpCodes.Nop); propertySetterIL.Emit(OpCodes.Ret); property.SetSetMethod(propertySetter); } } } return(typeBuilder.CreateType()); }
private static bool IsTwoColumnField(SPFieldAttribute field) { return(field.Type == SPFieldType.Lookup || field.Type == SPFieldType.User || field.Type == SPFieldType.URL); }
private SPModelDescriptor(Type targetType, SPModelDefaultsAttribute defaultsAttribute) { this.ModelType = targetType; TargetTypeDictionary.TryAdd(targetType, this); TargetTypeDictionary.TryGetValue(targetType.BaseType, out this.Parent); if (this.Parent is SPModelInterfaceTypeDescriptor) { this.Parent = null; } this.contentTypeAttribute = targetType.GetCustomAttribute <SPContentTypeAttribute>(false); ResolveContentTypeId(contentTypeAttribute, targetType); ContentTypeDictionary.Add(contentTypeAttribute.ContentTypeId, this); this.defaultManagerType = GetDefaultManagerType(targetType); this.provisionEventReceiverType = contentTypeAttribute.ProvisionEventReceiverType; this.hasExplicitListAttribute = targetType.GetCustomAttribute <SPListAttribute>(false) != null; this.listAttribute = targetType.GetCustomAttribute <SPListAttribute>(true) ?? new SPListAttribute(); this.fieldAttributes = SPModelFieldAssociationCollection.EnumerateFieldAttributes(this, targetType).ToArray(); if (contentTypeAttribute.Group == null && defaultsAttribute != null) { contentTypeAttribute.Group = defaultsAttribute.DefaultContentTypeGroup; } foreach (SPFieldAttribute attribute in fieldAttributes) { if (attribute.Group == null) { if (this.Parent != null) { SPFieldAttribute baseAttribute = this.Parent.fieldAttributes.FirstOrDefault(v => v.InternalName == attribute.InternalName); if (baseAttribute != null) { attribute.Group = baseAttribute.Group; continue; } } if (defaultsAttribute != null) { attribute.Group = defaultsAttribute.DefaultFieldGroup; } } } if (contentTypeAttribute.ContentTypeId.IsChildOf(ContentTypeId.Page)) { this.ItemType = SPModelItemType.PublishingPage; } else if (contentTypeAttribute.ContentTypeId.IsChildOf(SPBuiltInContentTypeId.DocumentSet)) { this.ItemType = SPModelItemType.DocumentSet; } else if (contentTypeAttribute.ContentTypeId.IsChildOf(SPBuiltInContentTypeId.Folder)) { this.ItemType = SPModelItemType.Folder; } else if (contentTypeAttribute.ContentTypeId.IsChildOf(SPBuiltInContentTypeId.Document)) { this.ItemType = SPModelItemType.File; } if (this.ItemType == SPModelItemType.GenericItem) { this.baseType = SPBaseType.GenericList; } else if (contentTypeAttribute.ContentTypeId.IsChildOf(SPBuiltInContentTypeId.Issue)) { this.baseType = SPBaseType.Issue; } else { this.baseType = SPBaseType.DocumentLibrary; } if (this.Parent != null) { this.Parent.Children.Add(this); this.fieldAttributes = fieldAttributes.Concat(this.Parent.fieldAttributes).Distinct().ToArray(); if (provisionEventReceiverType == null) { this.provisionEventReceiverType = this.Parent.provisionEventReceiverType; } } foreach (SPFieldAttribute v in fieldAttributes) { AddRequiredViewField(v); } foreach (Type interfaceType in targetType.GetInterfaces()) { if (!interfaceType.IsDefined(typeof(SPModelIgnoreAttribute), true)) { SPModelInterfaceTypeDescriptor interfaceDescriptor = (SPModelInterfaceTypeDescriptor)TargetTypeDictionary.EnsureKeyValue(interfaceType, SPModelInterfaceTypeDescriptor.Create); interfaceDescriptor.AddImplementedType(this); this.Interfaces.Add(interfaceDescriptor); } } if (targetType.BaseType != typeof(SPModel) && targetType.BaseType.GetCustomAttribute <SPContentTypeAttribute>(false) == null) { SPModelInterfaceTypeDescriptor interfaceDescriptor = (SPModelInterfaceTypeDescriptor)TargetTypeDictionary.EnsureKeyValue(targetType.BaseType, SPModelInterfaceTypeDescriptor.Create); interfaceDescriptor.AddImplementedType(this); this.Interfaces.Add(interfaceDescriptor); } if (!targetType.IsAbstract) { instanceType = new Lazy <Type>(() => targetType); } else { instanceType = new Lazy <Type>(() => SPModel.BuildTypeFromAbstractBaseType(targetType), LazyThreadSafetyMode.ExecutionAndPublication); } }