7

I am trying to create an an extension method to get all children of a derived type. This would be an extension method on my base glass item. But it returns null. Here is my method:

I register my types for preload like this:

var attributes = new AttributeConfigurationLoader("DD.Domain");
return new IConfigurationLoader[]{ attributes };  

My base glass item has a Children property like this:

[SitecoreType(AutoMap = true)]
public partial interface IBaseGlassItem : ISitecoreItem
{
    [SitecoreChildren(InferType = true)]
    IEnumerable<IBaseGlassItem> Children { get; }
}

public partial interface ISitecoreItem
{
    [SitecoreId]
    ID ID { get; set; }
    [SitecoreInfo(SitecoreInfoType.TemplateId)]
    ID TemplateID { get; set; }
}

Then I try to get some items:

public static IEnumerable<TChild> GetChildrenDerivedFrom<TChild>(this IBaseGlassItem item, ID templateId)
         where TChild : class, IBaseGlassItem
    {           
        var children = item.Children.Where(c => c.IsDerived(templateId)).OfType<TChild>();
        return children;
    }

And here is my type that I am actually trying to get:

[SitecoreType(AutoMap = true, TemplateId = PromotionOrEventDetailsFieldsConstants.TemplateIdString)]
public interface IPromotionOrEventDetailFields : IBaseGlassItem
{
    [SitecoreField]
    Image Image { get; set; }

    [SitecoreField]
    string HoverText { get; set; }

    [SitecoreField]
    string ShortTitle { get; set; }

    [SitecoreField]
    string Caption { get; set; }

    [SitecoreField]
    Item ColorTheme { get; set; }
}

But this never works because the .OfType<Tchild> ends up returning null because it thinks the children are of type IBaseGlassItem.

I suspect that maybe my types are not registered but how can I confirm this?

UPDATE

I figured out how to view what Glass Mapper has registered, and that is not the problem. My item is registered.

3
  • Are there any other properties exposed on other partial instances of the IBaseGlassItem? The reason I ask is that I'm pretty sure the the InferType functionality requires at least a property exposing the Template ID (and possibly Item ID) for it to work. Additionally, are your 'derived' models passing in the TemplateID parameter to the SitecoreType attribute? Dec 9, 2016 at 16:13
  • @EthanSchofer, since you figured out how to confirm that your types are registered, consider posting what you found as a solution and move subsequent debugging to the #glass channel of the Sitecore Community Slack. You will get better debugging help there and can always post another Question and Answer (or update this one) with the end-solution. Dec 9, 2016 at 18:18
  • 2
    Although this is unrelated to your issue , I just wanted to add that you don't need the line .Where(c => c.IsDerived(templateId)). The OfType<TChild> call should already filter down the children to just the template you're interested in, thanks to InferType already using the most-derived type for each model. Dec 9, 2016 at 18:28

3 Answers 3

3

In the line where you're returning a new IConfigurationLoader, you're not adding the attributes variable to the array:

var attributes = new AttributeConfigurationLoader("DD.Domain");
return new IConfigurationLoader[]{};

Update the return line to this and it should work:

return new IConfigurationLoader[]{ attributes };
0

Things to Confirm First

Make sure that on all your glass interfaces that inherit your IBaseGlassItem type you specify the TemplateID parameter of the [SitecoreType(...)] attribute (used to decorate the type itself).

Also make sure that you specify the glass interface's TemplateID property (you can call it something else, if you want to) and decorate it with the [SitecoreInfo(SitecoreInfoType.TemplateId)] on your IBaseGlassItem, as well.

Without these changes, your container will not be able to infer the type of your model, thus making the inferType parameter into a proverbial paperweight. This is because Glass.Mapper must be able to compare the TemplateID of the "item proxy" that is being cast to IBaseGlassItem with the types that Castle Windsor registered on App_Start.

Listing Registered Types with Castle Windsor

While I have not done this myself, if you are using Castle Windsor with Glass.Mapper then the following code (copied from this post) may work:

IWindsorContainer container = ...

foreach (var handler in container.Kernel.GetAssignableHandlers(typeof(object))) {
    Console.WriteLine("{0} {1}", 
       handler.ComponentModel.Service, 
       handler.ComponentModel.Implementation);
}

Listing Registered Types with Unity

If you are using Unity with Glass.Mapper, then this page of the Unity MSDN documentation may have what you are looking for. The relevant code is this example method on the page for writing information for all registrations to the Console (which you would probably just change to Log.Audit and trim the logged information to be more specific to your needs):

void DisplayContainerRegistrations(IUnityContainer theContainer)
{
    string regName, regType, mapTo, lifetime;
    Console.WriteLine("Container has {0} Registrations:",
            theContainer.Registrations.Count());

    foreach (ContainerRegistration item in theContainer.Registrations)
    {
        regType = item.RegisteredType.Name;
        mapTo = item.MappedToType.Name;
        regName = item.Name ?? "[default]";
        lifetime = item.LifetimeManagerType.Name;

        if (mapTo != regType)
        {
            mapTo = " -> " + mapTo;
        }
        else
        {
            mapTo = string.Empty;
        }

        lifetime = lifetime.Substring(0, lifetime.Length - "LifetimeManager".Length);

        Console.WriteLine("+ {0}{1}  '{2}'  {3}", regType, mapTo, regName, lifetime);
    }
}
0

My problem is not solved, but technically I figured out the answer to my question, which was how to view what is registered by Glass.

In GlassMapperSc.cs, which comes with Glass MApper, you can view the GlassContext and peruse the TypeConfigurations property to view what is registered.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.