示例#1
0
        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());
        }
示例#2
0
        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);
            }
        }