Sitecore Glass Mapper: Attributes on interfaces or concrete classes?
Asked Answered
I

2

5

We're new to Glass mapper and wanted to use it in our Sitecore project. When looking at the tutorials we noticed there were no deep examples of how to set up the deep inheritance that Sitecore allows. When browsing the web we noticed that there's people working with placing the attributes on the interfaces and on the other side there's people placing the attributes on the concrete classes. None of these examples explain their good reason for doing so however leaving us with the question: which is the correct use and what is the impact of doing one or the other?

Consider the following:

Template: Content (which is a field section template adding 2 simple fields: Title, Body) This template is directly and indirectly inherited by many of our templates.

Now in one of our sublayouts we use only this section and it is sort of a more general control thus we need to do: GetCurrentItem<Content> or GetCurrentItem<IContent>.

Personally I find the GetCurrentItem<IContent> more intuitive as it feels like asking: "Give me the current item if it supports the content section" where the other feels more like "Give me the current item if it is a content section" (which technically is impossible since Content Items are never created)

Isoagglutination answered 3/4, 2013 at 9:39 Comment(0)
M
9

Configuring an interface for Glass Mapper can serve a couple purposes. First off, Glass Mapper can actually create dynamic proxy objects based on your interface. This means that you can actually use Glass Mapper based on an interface alone, without your own concrete implementation.

Mike Edwards describes this here.

Behind the scenes Glass.Sitecore.Mapper mapper detects that you are using an interface and uses Castle Dynamic Proxies to generate a concrete class that your application can use.

As he points out, this adds some overhead and does make it impossible to add additional logic.

The other use is type inference. This isn't documented well in context of interfaces, but either in calling SitecoreService or in your field attributes, ask Glass Mapper to infer types. For this behavior, you shouldn't need to map the interface fields. Be sure to include the TemplateId on the SitecoreClass attribute of your concrete class. This should allow you to model multiple inheritance.

public interface ISitecoreItem {

    Guid ID{ get; }

    Language Language{ get; }

    int Version { get; }

    string Url { get; }
}

[SitecoreClass]
public partial interface IHeader : MyProject.Content.ISitecoreItem 
{

    Link LogoLink  {get; set;}

    Image Logo  {get; set;}

}



    [SitecoreClass(TemplateId="87d5b6c1-a084-4738-be11-b4e6fe07d894")]
    public partial class Header  : IHeader 
    {
        [SitecoreId]
        public virtual Guid ID{ get; private set;}

        [SitecoreInfo(SitecoreInfoType.Language)]
        public virtual Language Language{ get; private set; }

        [SitecoreInfo(SitecoreInfoType.Version)]
        public virtual int Version { get; private set; }

        [SitecoreInfo(SitecoreInfoType.Url)]
        public virtual string Url { get; private set; }

        [SitecoreField(FieldName = "Logo Link" )]
        public virtual Link LogoLink  {get; set;}

        [SitecoreField(FieldName = "Logo" )]
        public virtual Image Logo  {get; set;}


    }

var service = new SitecoreService(Sitecore.Context.Database);
var header = service.CreateClass<IHeader>(false /* don't lazy load */, true /* infer type */, headerItem);
Mitran answered 3/4, 2013 at 13:56 Comment(3)
Thank you, this was the explanation I was looking for. I hope the infer type functionality will be better documented in the future.Isoagglutination
You can add additional logic to interfaces by using extension methods. It's not ideal, of course.Md
The first link is broken, do you know if there is a new link for it?Piggery
H
2

I find modeling my Sitecore templates using interfaces to, generally, be the better option. This allows me to model my template structure in code much like it exists in Sitecore. For instance,

public interface IMyPageTemplate : IBaseTemplate1, IBaseTemplate2 {

}

It is much more difficult to model our templates with concrete classes since we generally have a number of base templates. Perhaps it is worth considering (although, I've not tried this) some sort of combination of interfaces and concrete classes. Maybe, templates that are strictly base templates, like IContent should be modeled as interfaces and all templates that can be created as content should be modeled as concrete classes.

It is valid to do something like GetCurrentItem<IContent>(). It's just worth noting that what gets returned is a proxy class which can provide it's own challenges (depending on what you are doing).

Hussein answered 3/4, 2013 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.