Don't forget a driver foreach part

Topics: Writing modules
Mar 22, 2011 at 2:36 PM
FACT: When contentItem.As<YourPart>() returns null while the typedefinition is correct the solution is to create a driver for your content item...

For whoever reads this, your information, ALWAYS create a driver for a part!

I did spend 2 hours debugging today why o why my part wasn't correctly being weld on my contentItem, so contentItem.As<MyPart>() returns null

I made a new part and created a handler. Since the part would never be visible and contains only information about the contentItem i didn't made a driver.
I altered the type definition of the contenttype with the new part and welding didn't show the enough details about the part... arg!@# :)

The reason behind this is because the ContentPartDriverCoordinator is responsable for welding parts on a contentItem.
If there is no driver for the part then there is no PartInfo, resulting in a unknown part.

        public override void Activating(ActivatingContentContext context) {
            var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
            if (contentTypeDefinition == null)
                return;

            var partInfos = _drivers.SelectMany(cpp => cpp.GetPartInfo());

            foreach (var typePartDefinition in contentTypeDefinition.Parts) {
                var partName = typePartDefinition.PartDefinition.Name;
                var partInfo = partInfos.FirstOrDefault(pi => pi.PartName == partName);
                var part = partInfo != null 
                    ? partInfo.Factory(typePartDefinition) 
                    : new ContentPart { TypePartDefinition = typePartDefinition };
                context.Builder.Weld(part);
            }
        }
May 3, 2011 at 10:17 AM

A driver may not be needed, you may just also add a ContentHandler Filter :

public class MyPartHandler : ContentHandler {
   public MyPartHandler(IRepository<MyPartRecord> repository)
   {
       Filters.Add(new ActivatingFilter<MyPart>("MyContentType"));
       Filters.Add(StorageFilter.For(repository));
   }
}

 

May 3, 2011 at 10:19 AM
Edited May 3, 2011 at 10:22 AM

Didn't u read my post?

Not to be rude, but if u want to access parts within a contentitem using the extension method ".As<>" u'll need a driver even if a driver isn't needed create a shape.

May 3, 2011 at 1:03 PM
Edited May 3, 2011 at 1:05 PM

We may not had the same problem. What I wanted to do is add a new content part to an existing content type "User".

I create a content part class with its associated record class and an handler with just Filters.Add(StorageFilter.For(repository));

In the Migrations class, I create a new table and believe that with

ContentDefinitionManager.AlterTypeDefinition("User",
              cfg => cfg
                 .WithPart("MyPart")
              );

I could do : var part = user.ContentItem.As<MyPart>(); and it should not be null.

That's not the case. I remove the AlterTypeDefinition and add Filters.Add(new ActivatingFilter<MyPart>("User")); in my handler and it works. No driver class for my content part.