3

I have a multilist field on an item that can contain items from different templates. I was wondering if there was any way to map this field in such a way that the objects are mapped to the correct model based on their template. So for example:

public interface IPerson
{
    string FullName {get; set;}
}

[SitecoreType(TemplateId="....")]
public class Professor
{
    [SitecoreField]
    public string Prefix {get; set;}
    [SitecoreField]
    public string FirstName {get; set;}
    [SitecoreField]
    public string LastName {get; set;}

    public string FullName
    {
        return string.format("{0} {1} {2}", Prefix, FirstName, LastName)
    }
}

[SitecoreType(TemplateId="....")]
public class Student
{
    [SitecoreField]
    public string FirstName {get; set;}
    [SitecoreField]
    public string LastName {get; set;}

    public string FullName
    {
        return string.format("{0} {1}", FirstName, LastName)
    }
}

[SitecoreType(TemplateId="....")]
public class ClassSession
{
    [SitecoreField]
    public IEnumerable<IPerson> Participants {get; set;}
}

In this instance I'd like the Participants property to contain Student and Professor objects since they implement the Fullname property differently.

Kyle
  • 4,261
  • 11
  • 46
  • 85

1 Answers1

6

You can use infer types in Glass.mapper, Inferred types allows you to load a more specific type based on the template of the item being loaded. :

public interface IPerson
{
    string FullName {get; set;}
}

[SitecoreType(TemplateId="....", AutoMap = true)]
public class Professor : IPerson
{
    [SitecoreField]
    public string Prefix {get; set;}
    [SitecoreField]
    public string FirstName {get; set;}
    [SitecoreField]
    public string LastName {get; set;}

    public string FullName
    {
        return string.format("{0} {1} {2}", Prefix, FirstName, LastName)
    }
}

[SitecoreType(TemplateId="....", AutoMap = true)]
public class Student : IPerson
{
    [SitecoreField]
    public string FirstName {get; set;}
    [SitecoreField]
    public string LastName {get; set;}

    public string FullName
    {
        return string.format("{0} {1}", FirstName, LastName)
    }
}

[SitecoreType(TemplateId="....", AutoMap = true)]
public class ClassSession
{
    [SitecoreField(Setting = SitecoreFieldSettings.InferType)]
    public IEnumerable<IPerson> Participants {get; set;}
}

Notice that i added AutoMap = true in your classes atrributes, and changed your multilist property attribute to be like:

[SitecoreField(Setting = SitecoreFieldSettings.InferType)]

For more details, go to mike tutorials here: http://glass.lu/docs/tutorial/sitecore/tutorial17/tutorial17.html

Edit:

You need to include your assembly in configurations loader, find the GlassMapperScCustom class in your solution. You should then update the GlassLoaders method:

public static IConfigurationLoader[] GlassLoaders()
    {
        var attributes = new AttributeConfigurationLoader("Your assembly name");

        return new IConfigurationLoader[] {attributes };
    }
Ahmed Okour
  • 2,392
  • 1
  • 16
  • 31
  • Thanks @Ahmed. This looks exactly like what I want, unfortunately it is not working. The items are still getting mapped as `IPersonProxy` and the fields are not populated correctly. – Kyle Aug 29 '14 at 14:15
  • I just updated my answer, there is one last step you need to do – Ahmed Okour Aug 29 '14 at 14:20
  • I'm now getting "You can not have duplicate mappings for properties. Property Name: Name Type: Name" on this line in `GlassMapperSc`: `context.Load(GlassMapperScCustom.GlassLoaders());` – Kyle Aug 29 '14 at 14:24
  • Not sure why you are getting that, i just checked the code causing this exception, and it seems there are some duplicate properties in one of your models. Line 81: https://github.com/mikeedwards83/Glass.Mapper/blob/master/Source/Glass.Mapper/Configuration/AbstractTypeConfiguration.cs – Ahmed Okour Aug 29 '14 at 14:34
  • What exactly does that mean? The same Sitecore field is being mapped to two different properties? If so I do that quite often in the case of Multilist fields so that I can use the same models for doing Sitecore Search queries. I map the raw value to `IEnumerable` and then also have a property for `IEnumerable` – Kyle Aug 29 '14 at 14:42
  • I'm not sure, but to figure that out, include glass mapper source code in your project and debug that function 'AddProperty' to know exactly what went wrong – Ahmed Okour Aug 29 '14 at 14:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60240/discussion-between-ahmed-okour-and-kyle). – Ahmed Okour Aug 29 '14 at 14:49