Наследование: CodeFirstRegistration
        protected object CreateInstanceFromContent(IContentBase content, ContentTypeRegistration registration, CodeFirstModelContext parentContext = null)
        {
            Dictionary <PropertyInfo, CodeFirstLazyInitialiser> dict;
            var instance = CodeFirstModelContext.CreateContextualInstance(registration.ClrType, registration, out dict, parentContext, false);

            //properties on Generic Tab
            foreach (var property in registration.Properties)
            {
                CopyPropertyValueToModel(content, instance, property);
            }

            foreach (var tab in registration.Tabs)
            {
                //tab instance
                Dictionary <PropertyInfo, CodeFirstLazyInitialiser> tabDict;
                var tabInstance = CodeFirstModelContext.CreateContextualInstance(tab.ClrType, tab, out tabDict);
                foreach (var property in tab.Properties)
                {
                    CopyPropertyValueToModel(content, tabInstance, property);
                }
                tab.PropertyOfParent.SetValue(instance, tabInstance);
            }

            foreach (var composition in registration.Compositions)
            {
                CodeFirstModelContext.MoveNextContext(instance, composition);
                composition.PropertyOfContainer.SetValue(instance, CreateInstanceFromContent(content, composition, CodeFirstModelContext.GetContext(instance)));
            }

            return(instance);
        }
Пример #2
0
        protected override IContentTypeBase UpdateContentType(ContentTypeRegistration registration, out bool modified)
        {
            var result = base.UpdateContentType(registration, out modified);

            if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Ensure)
            {
                if (modified)
                {
                    throw new CodeFirstPassiveInitialisationException("The types defined in the database do not match the types passed in to initialise. In InitialisationMode.Ensure the types must match or the site will be prevented from starting.");
                }
                else
                {
                    return(result);
                }
            }
            else if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Sync)
            {
                if (modified)
                {
                    return(SyncMemberType(registration, result));
                }
                else
                {
                    return(result);
                }
            }
            else if (CodeFirstManager.Current.Features.InitialisationMode == InitialisationMode.Passive)
            {
                return(result);
            }
            else
            {
                throw new CodeFirstException("Unknown initialisation type");
            }
        }
        /// <summary>
        /// <para>Creates an IContent populated with the current values of the model</para>
        /// </summary>
        private IContent CreateContent(int parentId, DocumentTypeBase model, ContentTypeRegistration registration)
        {
            //Get the type alias and create the content
            var typeAlias = registration.Alias;
            var node      = ApplicationContext.Current.Services.ContentService.CreateContent(model.NodeDetails.Name, parentId, typeAlias);

            MapModelToContent(node, model, registration);
            return(node);
        }
Пример #4
0
 protected override void SyncAllowedChildren(ContentTypeRegistration registration)
 {
     if (CodeFirstManager.Current.Features.AllowAllMediaTypesInDefaultFolder && registration.ClrType == typeof(MediaFolder))
     {
         //TODO make this an attribute so it can be used on user-created folders too. Maybe all it on doc types too. Need separate attrs though as separate types of potential children.
         AddAllTypesToAllowedChildren(registration);
     }
     base.SyncAllowedChildren(registration);
 }
        /// <summary>
        /// Updates an existing IContent item with the current values of the model
        /// </summary>
        /// <returns></returns>
        private IContent UpdateContent(DocumentTypeBase model, ContentTypeRegistration registration)
        {
            if (model.NodeDetails == null || model.NodeDetails.UmbracoId == -1)
            {
                throw new ArgumentException("Can't update content for a model with no ID. Try calling CreateContent instead. Check that the NodeDetails.UmbracoId property is set before calling UpdateContent.");
            }
            var node = ApplicationContext.Current.Services.ContentService.GetById(model.NodeDetails.UmbracoId);

            MapModelToContent(node, model, registration);
            return(node);
        }
        /// <summary>
        /// <para>Creates an IContent populated with the current values of the model</para>
        /// </summary>
        private IMedia CreateContent(int parentId, MediaTypeBase model, ContentTypeRegistration registration)
        {
            //Get the type alias and create the content
            var typeAlias = registration.Alias;
            var node      = ApplicationContext.Current.Services.MediaService.CreateMedia(model.NodeDetails.Name, parentId, typeAlias);

            MapModelToContent(node, model, registration);
            if (model.MediaFile != null && node.HasProperty("umbracoFile"))
            {
                var fn = System.IO.Path.GetFileName(model.MediaFile.Name);
                node.SetValue("umbracoFile", fn, model.MediaFile);
            }
            return(node);
        }
            public void Register(ContentTypeRegistration registration)
            {
                if (!_instance._registerByAlias.TryAdd(registration.Alias, registration))
                {
                    throw new CodeFirstException("Document type alias already registered");
                }

                if (!_instance._registerByType.TryAdd(registration.ClrType, registration))
                {
                    ContentTypeRegistration r;
                    _instance._registerByAlias.TryRemove(registration.Alias, out r);
                    throw new CodeFirstException("Document type CLR type already registered");
                }
            }
        /// <summary>
        /// Updates an existing IContent item with the current values of the model
        /// </summary>
        /// <returns></returns>
        private IMedia UpdateContent(MediaTypeBase model, ContentTypeRegistration registration)
        {
            if (model.NodeDetails == null || model.NodeDetails.UmbracoId == -1)
            {
                throw new ArgumentException("Can't update content for a model with no ID. Try calling CreateContent instead. Check that the NodeDetails.UmbracoId property is set before calling UpdateContent.");
            }
            var node = ApplicationContext.Current.Services.MediaService.GetById(model.NodeDetails.UmbracoId);

            MapModelToContent(node, model, registration);
            if (model.MediaFile != null && node.HasProperty("umbracoFile"))
            {
                node.SetValue("umbracoFile", System.IO.Path.GetFileNameWithoutExtension(model.MediaFile.Name), model.MediaFile);
            }
            return(node);
        }
 public virtual void CreateOrUpdateContentType(ContentTypeRegistration registration)
 {
     bool modified;
     IContentTypeBase contentType;
     if (!AllContentTypes.Any(x => x != null && string.Equals(x.Alias, registration.ContentTypeAttribute.Alias, StringComparison.InvariantCultureIgnoreCase)))
     {
         contentType = CreateContentType(registration, out modified);
     }
     else
     {
         contentType = UpdateContentType(registration, out modified);
     }
     if (modified)
     {
         contentType.ResetDirtyProperties(false);
         Save(contentType);
     }
 }
Пример #10
0
        private void AddAllTypesToAllowedChildren(ContentTypeRegistration mediaTypeReg)
        {
            var list = new List <Type>();

            if (mediaTypeReg.ContentTypeAttribute.AllowedChildren != null) //Add specified children
            {
                list.AddRange(mediaTypeReg.ContentTypeAttribute.AllowedChildren);
            }
            foreach (var reg in ContentTypeRegister.Registrations) //Add all other types
            {
                if (!list.Contains(reg.ClrType))
                {
                    list.Add(reg.ClrType);
                }
            }
            if (!list.Contains(mediaTypeReg.ClrType)) //Add self
            {
                list.Add(mediaTypeReg.ClrType);
            }
            mediaTypeReg.ContentTypeAttribute.AllowedChildren = list.ToArray();
        }
Пример #11
0
        /// <summary>
        /// <para>Creates an IMember populated with the current values of the model</para>
        /// </summary>
        private IMember CreateContent(MemberTypeBase model, ContentTypeRegistration registration)
        {
            if (model.Name == null)
            {
                throw new CodeFirstException("Name must be set to create a member");
            }
            if (model.Username == null)
            {
                throw new CodeFirstException("Username must be set to create a member");
            }
            if (model.Email == null)
            {
                throw new CodeFirstException("Email must be set to create a member");
            }

            //Get the type alias and create the content
            var typeAlias = registration.Alias;
            var node      = ApplicationContext.Current.Services.MemberService.CreateMemberWithIdentity(model.Username, model.Email, model.Name, typeAlias);

            SetMemberSpecificProperties(model, node);
            MapModelToContent(node, model, registration);
            return(node);
        }
Пример #12
0
        private IContentTypeBase SyncMemberType(ContentTypeRegistration registration, IContentTypeBase result)
        {
            result.ResetDirtyProperties(false);
            Save(result); //need to save to ensure no sync issues when we load from the legacy API
            bool modified = false;
            var  member   = new umbraco.cms.businesslogic.member.MemberType(result.Id);

            foreach (var prop in member.PropertyTypes)
            {
                var propReg = registration.Properties.SingleOrDefault(x => x.Alias == prop.Alias);
                if (propReg != null)
                {
                    var attr = propReg.Metadata.GetCodeFirstAttribute <MemberPropertyAttribute>();
                    if (attr != null)
                    {
                        if (attr.MemberCanEdit != member.MemberCanEdit(prop))
                        {
                            member.setMemberCanEdit(prop, attr.MemberCanEdit);
                            modified = true;
                        }
                        if (attr.ShowOnProfile != member.ViewOnProfile(prop))
                        {
                            member.setMemberViewOnProfile(prop, attr.ShowOnProfile);
                            modified = true;
                        }
                    }
                }
            }

            if (modified)
            {
                modified = false;
                member.Save();
            }

            return(_service.Get(member.Id));
        }
        protected object CreateInstanceFromPublishedContent(IPublishedContent content, ContentTypeRegistration registration, CodeFirstModelContext parentContext = null)
        {
            Dictionary <PropertyInfo, CodeFirstLazyInitialiser> dict;
            var instance = CodeFirstModelContext.CreateContextualInstance(registration.ClrType, registration, out dict, parentContext);

            //properties on Generic Tab
            foreach (var property in registration.Properties)
            {
                if (CodeFirstManager.Current.Features.UseLazyLoadingProxies && property.Metadata.GetGetMethod().IsVirtual)
                {
                    dict.Add(property.Metadata, new CodeFirstLazyInitialiser(() => CopyPropertyValueToModel(content, instance, property)));
                }
                else
                {
                    CopyPropertyValueToModel(content, instance, property);
                }
            }

            foreach (var tab in registration.Tabs)
            {
                //tab instance
                Dictionary <PropertyInfo, CodeFirstLazyInitialiser> tabDict;
                var tabInstance = CodeFirstModelContext.CreateContextualInstance(tab.ClrType, tab, out tabDict);
                foreach (var property in tab.Properties)
                {
                    if (CodeFirstManager.Current.Features.UseLazyLoadingProxies && property.Metadata.GetGetMethod().IsVirtual)
                    {
                        tabDict.Add(property.Metadata, new CodeFirstLazyInitialiser(() => CopyPropertyValueToModel(content, tabInstance, property)));
                    }
                    else
                    {
                        CopyPropertyValueToModel(content, tabInstance, property);
                    }
                }
                tab.PropertyOfParent.SetValue(instance, tabInstance);
            }

            foreach (var composition in registration.Compositions)
            {
                var parent = CodeFirstModelContext.GetCompositionParentContext(composition);
                if (CodeFirstManager.Current.Features.UseLazyLoadingProxies && composition.PropertyOfContainer.GetGetMethod().IsVirtual)
                {
                    dict.Add(composition.PropertyOfContainer, new CodeFirstLazyInitialiser(() => composition.PropertyOfContainer.SetValue(instance, CreateInstanceFromPublishedContent(content, composition, parent))));
                }
                else
                {
                    composition.PropertyOfContainer.SetValue(instance, CreateInstanceFromPublishedContent(content, composition, parent));
                }
            }

            CodeFirstModelContext.ResetContext();
            return(instance);
        }
 public bool TryGetContentType(Type type, out ContentTypeRegistration registration)
 {
     try
     {
         registration = GetRegistration(type);
         return true;
     }
     catch
     {
         registration = null;
         return false;
     }
 }
        /// <summary>
        /// Update the existing content Type based on the data in the attributes
        /// </summary>
        /// <param name="contentTypeService"></param>
        /// <param name="attribute"></param>
        /// <param name="contentType"></param>
        /// <param name="type"></param>
        /// <param name="dataTypeService"></param>
        protected virtual IContentTypeBase UpdateContentType(ContentTypeRegistration registration, out bool modified)
        {
            CodeFirstManager.Current.Log("Syncing content type for " + registration.ClrType.FullName, this);
            var contentType = GetContentTypeByAlias(registration.ContentTypeAttribute.Alias);
            modified = false;

            //Get parent info
            ContentTypeAttribute parentAttribute;
            Type parentType;
            GetCodeFirstParent(registration.ClrType, out parentAttribute, out parentType);
            var parentContent = parentAttribute == null ? null : GetContentTypeByAlias(parentAttribute.Alias);
            var oldParent = AllContentTypes.FirstOrDefault(x => x.Id == contentType.ParentId);
            int targetParentId = parentContent == null ? -1 : parentContent.Id;

            //Check if parent has changed
            if (contentType.ParentId != targetParentId)
            {
                contentType = Reparent(registration, contentType, parentContent, oldParent);
            }

            var existingChildrenAliases = contentType.AllowedContentTypes.Select(x => x.Alias);
            modified = !contentType.Name.Equals(registration.ContentTypeAttribute.Name, StringComparison.InvariantCultureIgnoreCase) ||
                       !contentType.Alias.Equals(registration.ContentTypeAttribute.Alias, StringComparison.InvariantCultureIgnoreCase) ||
                       !contentType.Icon.Equals(registration.ContentTypeAttribute.Icon, StringComparison.InvariantCultureIgnoreCase) ||
                       contentType.IsContainer != registration.ContentTypeAttribute.EnableListView ||
                       contentType.AllowedAsRoot != registration.ContentTypeAttribute.AllowedAtRoot;

            if (contentType.Description != registration.ContentTypeAttribute.Description)
            {
                //If not both null/empty
                if (!(string.IsNullOrEmpty(contentType.Description) && string.IsNullOrEmpty(registration.ContentTypeAttribute.Description)))
                {
                    modified = true;
                }
            }

            contentType.Name = registration.ContentTypeAttribute.Name;
            contentType.Alias = registration.ContentTypeAttribute.Alias;
            contentType.Icon = registration.ContentTypeAttribute.Icon;
            contentType.Description = registration.ContentTypeAttribute.Description;
            contentType.IsContainer = registration.ContentTypeAttribute.EnableListView;
            contentType.AllowedAsRoot = registration.ContentTypeAttribute.AllowedAtRoot;

            VerifyProperties(contentType, registration.ClrType, registration._properties, registration._tabs, ref modified);

            //verify if a tab has no properties, if so remove
            //NB need to protect against removal of tabs declared on composition or ancestor types (note that ancestors show up in the composition collections so only that check is needed)
            var localPropertyGroups = contentType.PropertyGroups.Where(x => !contentType.CompositionPropertyGroups.Contains(x)).ToArray();
            var protectedTabs = registration.ClrType.GetCustomAttributes<DoNotRemoveTabAttribute>(true).Select(x => x.TabName);
            int length = localPropertyGroups.Length;
            for (int i = 0; i < length; i++)
            {
                if (localPropertyGroups[i].PropertyTypes.Count == 0 && !protectedTabs.Any(x => localPropertyGroups[i].Name.Equals(x, StringComparison.InvariantCultureIgnoreCase)))
                {
                    modified = true;
                    //remove
                    contentType.RemovePropertyGroup(localPropertyGroups[i].Name);
                }
            }

            if (modified)
            {
                CheckBuiltIn(registration);
            }

            return contentType;
        }
 public ContentTypeCompositionRegistration(ContentTypeRegistration basis, PropertyInfo propertyOfContainer)
 {
     _basis = basis;
     PropertyOfContainer = propertyOfContainer;
 }
 public bool TryGetContentType(string alias, out ContentTypeRegistration registration)
 {
     return _registerByAlias.TryGetValue(alias, out registration);
 }
 private void ValidateComposition(ContentTypeRegistration docTypeReg, List<ContentTypeRegistration> targetBases, PropertyInfo comp, ContentTypeRegistration compReg, List<ContentTypeRegistration> usedInCompositions)
 {
     if (compReg.ClrType == docTypeReg.ClrType) //validate compose with self
     {
         throw new CodeFirstException(docTypeReg.ClrType.Name + " declares a composition with itself. Property name: " + comp.Name);
     }
     else if (docTypeReg.ClrType.Inherits(compReg.ClrType)) //validate compose with ancestor
     {
         throw new CodeFirstException(docTypeReg.ClrType.Name + " declares a composition with an ancestor. Property name: " + comp.Name + ", Ancestor type: " + compReg.ClrType.Name);
     }
     else if (compReg.ClrType.Inherits(docTypeReg.ClrType)) //validate compose with descendant
     {
         throw new CodeFirstException(docTypeReg.ClrType.Name + " declares a composition with a descendant. Property name: " + comp.Name + ", Descendant type: " + compReg.ClrType.Name);
     }
     else if (usedInCompositions != null && usedInCompositions.Contains(docTypeReg)) //validate compose of type which is used in compositions
     {
         throw new CodeFirstException(docTypeReg.ClrType.Name + " declares a composition but is used in other compositions or is used as a parent. Therefore it cannot be composed itself.");
     }
     else //validate compose with common ancestors
     {
         var sourceBases = GetAllAncestorTypes(compReg);
         var ancestors = sourceBases.Intersect(targetBases);
         if (ancestors.Any())
         {
             var ancestorString = string.Join(", ", ancestors.Select(x => x.ClrType.Name));
             throw new CodeFirstException(docTypeReg.ClrType.Name + " declares an invalid composition with " + compReg.ClrType.Name + ". The types have the following common ancestors: " + ancestorString);
         }
     }
 }
 private IContentTypeComposition Reparent(ContentTypeRegistration registration, IContentTypeComposition contentType, IContentTypeBase newParent, IContentTypeBase oldParent)
 {
     //TODO sort out reparenting
     throw new CodeFirstException("Changing parent types of existing content types is not supported. Consider dropping & recreating your content type hierarchy or using compositions instead." + Environment.NewLine +
         "Affected type alias: " + registration.Alias + ", previous parent alias: " + (oldParent == null ? "[none]" : oldParent.Alias) + ", new parent alias: " + (newParent == null ? "[none]" : newParent.Alias));
 }
        private List<ContentTypeCompositionRegistration> GetComposingTypes(ContentTypeRegistration docTypeReg, List<ContentTypeRegistration> usedInCompositions)
        {
            var result = new List<ContentTypeCompositionRegistration>();
            var compositionProperties = docTypeReg.ClrType.GetProperties().Where(x => x.GetCodeFirstAttribute<ContentCompositionAttribute>() != null);
            var targetBases = GetAllAncestorTypes(docTypeReg);

            foreach (var comp in compositionProperties)
            {
                ContentTypeRegistration compReg;
                if (TryGetContentType(comp.PropertyType, out compReg))
                {
                    ValidateComposition(docTypeReg, targetBases, comp, compReg, usedInCompositions);
                    result.Add(new ContentTypeCompositionRegistration(compReg, comp));
                }
                else
                {
                    throw new CodeFirstException("Property " + comp.Name + " has type " + comp.PropertyType.Name + " which is not a registered document type and cannot be used as a composition on document type " + docTypeReg.ClrType.Name);
                }
            }
            return result;
        }
 private List<ContentTypeRegistration> GetAllAncestorTypes(ContentTypeRegistration docTypeReg)
 {
     var targetBases = new List<ContentTypeRegistration>();
     var targetBase = docTypeReg.ClrType.BaseType;
     while (targetBase != null)
     {
         ContentTypeRegistration reg;
         if (TryGetContentType(targetBase, out reg))
         {
             targetBases.Add(reg);
         }
         targetBase = targetBase.BaseType;
     }
     return targetBases;
 }
 private void CheckBuiltIn(ContentTypeRegistration registration)
 {
     if (registration.ClrType.GetCustomAttribute<BuiltInTypeAttribute>(false) != null)
     {
         throw new CodeFirstException("A default type has been modified in the database. If you intend to modify the default types " +
                                      "you must switch off the equivalent code-first built-in types using the relevant property in " +
                                      "CodeFirstManager.Current.Features." + Environment.NewLine +
                                      "Affected type: " + registration.ClrType.Name + Environment.NewLine +
                                      "Built-in type category: " + registration.ClrType.GetCustomAttribute<BuiltInTypeAttribute>(false).BuiltInTypeName);
     }
 }
 public bool TryGetContentType(string alias, out ContentTypeRegistration registration)
 {
     try
     {
         registration = GetRegistration(alias);
         return true;
     }
     catch
     {
         registration = null;
         return false;
     }
 }
 public bool TryGetContentType(Type type, out ContentTypeRegistration registration)
 {
     type = StripProxy(type);
     return(_registerByType.TryGetValue(type, out registration));
 }
        protected void MapModelToContent(IContentBase node, CodeFirstContentBase <T> model, ContentTypeRegistration registration, bool firstLevel = true)
        {
            if (firstLevel)
            {
                node.Name      = model.NodeDetails.Name;
                node.SortOrder = model.NodeDetails.SortOrder;
            }

            foreach (var prop in registration.Properties)
            {
                var val = prop.Metadata.GetValue(model);
                if (val != null)
                {
                    SetPropertyOnContent(node, prop, val);
                }
            }

            //Get and then set all the properties from any tabs
            var tabs = registration.Tabs;

            foreach (var tab in tabs)
            {
                var tabInstance = tab.PropertyOfParent.GetValue(model);

                if (tabInstance != null)
                {
                    foreach (var prop in tab.Properties)
                    {
                        var val = prop.Metadata.GetValue(tabInstance);
                        if (val != null)
                        {
                            SetPropertyOnContent(node, prop, val);
                        }
                    }
                }
            }

            foreach (var comp in registration.Compositions)
            {
                MapModelToContent(node, (CodeFirstContentBase <T>)comp.PropertyOfContainer.GetValue(model), comp, false);
            }
        }
        protected virtual void SyncAllowedChildren(ContentTypeRegistration docTypeReg)
        {
            CodeFirstManager.Current.Log("Syncing allowed children for content type " + docTypeReg.Name, this);
            bool modified = false;
            var allowedChildren = FetchAllowedContentTypes(docTypeReg.ContentTypeAttribute.AllowedChildren, docTypeReg.ClrType);
            var type = GetContentTypeByAlias(docTypeReg.Alias);
            if (type == null)
            {
                throw new CodeFirstException(docTypeReg.Name + " (alias: " + docTypeReg.Alias + ") is not found or is an entity type which does not implement IContentTypeBase");
            }

            //REMOVED - Dan M 04/01/2016 - this is now checked in FetchAllowedContentTypes (or should be...)
            //Check that all specified allowed children are registered as CF types
            //foreach (var child in allowedChildren)
            //{
            //	ContentTypeRegistration childReg;
            //	if (!TryGetContentType(child.Alias, out childReg))
            //	{
            //		throw new CodeFirstException(string.Format("Type with alias {0} was specified as an allowed child of type with alias {1}, but no type with alias {0} is registered in code-first", child.Alias, type.Alias));
            //	}
            //}

            //Flag as modified if any existing children need to be removed
            foreach (var child in type.AllowedContentTypes)
            {
                if (!allowedChildren.Any(x => x.Alias == child.Alias))
                {
                    modified = true;
                    break;
                }
            }

            //If we haven't already detected any mods, check if any new allowed children have been added
            if (!modified)
            {
                foreach (var child in allowedChildren)
                {
                    if (!type.AllowedContentTypes.Any(x => x.Alias == child.Alias))
                    {
                        modified = true;
                        break;
                    }
                }
            }

            if (modified)
            {
                type.AllowedContentTypes = allowedChildren;
                type.ResetDirtyProperties(false);
                Save(type);
            }
        }
            public void Register(ContentTypeRegistration registration)
            {
                if (!_instance._registerByAlias.TryAdd(registration.Alias, registration))
                {
                    throw new CodeFirstException("Document type alias already registered");
                }

                if (!_instance._registerByType.TryAdd(registration.ClrType, registration))
                {
                    ContentTypeRegistration r;
                    _instance._registerByAlias.TryRemove(registration.Alias, out r);
                    throw new CodeFirstException("Document type CLR type already registered");
                }
            }
 protected void Register(ContentTypeRegistration registration)
 {
     _controller.Register(registration);
 }
 public bool TryGetContentType(Type type, out ContentTypeRegistration registration)
 {
     type = StripProxy(type);
     return _registerByType.TryGetValue(type, out registration);
 }
        /// <summary>
        /// This method is called when the Content Type declared in the attribute hasn't been found in Umbraco
        /// </summary>
        /// <param name="contentTypeService"></param>
        /// <param name="fileService"></param>
        /// <param name="attribute"></param>
        /// <param name="contentClrType"></param>
        /// <param name="dataTypeService"></param>
        protected virtual IContentTypeBase CreateContentType(ContentTypeRegistration registration, out bool modified)
        {
            CodeFirstManager.Current.Log("Creating content type for " + registration.ClrType.FullName, this);
            IContentTypeBase newContentType;
            modified = true; //always modify when we create (overriders may save and set this to false before returning though)

            ContentTypeAttribute parentAttribute;
            Type parentType;
            GetCodeFirstParent(registration.ClrType, out parentAttribute, out parentType);
            if (parentType != null && parentAttribute != null)
            {

                string parentAlias = parentAttribute.Alias;
                IContentTypeBase parentContentType = GetContentTypeByAlias(parentAlias);
                newContentType = CreateContentType(parentContentType);
            }
            else
            {
                IContentTypeBase fake = null;
                newContentType = CreateContentType(fake);
            }

            newContentType.Name = registration.ContentTypeAttribute.Name;
            newContentType.Alias = registration.ContentTypeAttribute.Alias;
            newContentType.Icon = registration.ContentTypeAttribute.Icon;
            newContentType.Description = registration.ContentTypeAttribute.Description;
            newContentType.AllowedAsRoot = registration.ContentTypeAttribute.AllowedAtRoot;
            newContentType.IsContainer = registration.ContentTypeAttribute.EnableListView;
            newContentType.AllowedContentTypes = new ContentTypeSort[0];

            //create tabs
            CreateTabs(newContentType, registration._tabs, registration.ClrType);

            //create properties on the generic tab
            var propertiesOfRoot = registration.ClrType.GetProperties().Where(x => x.GetCodeFirstAttribute<ContentPropertyAttribute>() != null);
            foreach (var item in propertiesOfRoot)
            {
                var reg = _propertyModule.CreateProperty(newContentType, null, item, registration.ClrType);
                registration._properties.Add(reg);
            }
            return newContentType;
        }
 public bool TryGetContentType(string alias, out ContentTypeRegistration registration)
 {
     return(_registerByAlias.TryGetValue(alias, out registration));
 }
        protected virtual void SyncCompositions(ContentTypeRegistration docTypeReg)
        {
            CodeFirstManager.Current.Log("Syncing compositions for content type " + docTypeReg.Name, this);
            bool modified = false;
            var type = GetContentTypeByAlias(docTypeReg.Alias);
            if (type == null)
            {
                throw new CodeFirstException(docTypeReg.Name + " (alias: " + docTypeReg.Alias + ") is not found or is an entity type which does not implement IContentTypeComposition");
            }
            var comps = GetComposingTypes(docTypeReg, _typesUsedInCompositions.Value);
            var toRemove = new List<IContentTypeComposition>();

            foreach (var comp in type.ContentTypeComposition)
            {
                ContentTypeRegistration compReg;
                if (!TryGetContentType(comp.Alias, out compReg) || (!docTypeReg.ClrType.Inherits(compReg.ClrType) && !comps.Contains(compReg)))
                {
                    //Not a registered code-first type or not an ancestor and not a defined composition. Remove.
                    toRemove.Add(comp);
                }
            }
            foreach (var comp in toRemove)
            {
                modified = true;
                CodeFirstManager.Current.Log("Removing composition with " + comp.Name + " from " + docTypeReg.Name, this);
                type.RemoveContentType(comp.Alias);
            }
            foreach (var comp in comps)
            {
                if (!type.ContentTypeCompositionExists(comp.Alias))
                {
                    modified = true;
                    CodeFirstManager.Current.Log("Adding composition with " + comp.Name + " to " + docTypeReg.Name, this);
                    var compType = GetContentTypeByAlias(comp.Alias);
                    try
                    {
                        type.AddContentType(compType);
                    }
                    catch (InvalidCompositionException ex)
                    {
                        throw new CodeFirstException("Invalid Composition - " + ex.Message, ex);
                    }
                }
            }

            docTypeReg._compositions = comps;

            if (modified)
            {
                Save(type);
            }
        }