Sitecore Glass Mapper:接口或具体类的属性?

时间:2013-04-03 09:39:55

标签: sitecore glass-mapper

我们是Glass mapper的新手,想在我们的Sitecore项目中使用它。在查看教程时,我们注意到没有深入的示例说明如何设置Sitecore允许的深度继承。在浏览网页时,我们注意到有人在界面上放置属性,另一方面有人将属性放在具体的类上。这些例子都没有解释他们这样做的好理由,但是给我们留下了一个问题:这是正确的用法,做一个或另一个的影响是什么?

请考虑以下事项:

模板:内容(添加2个简单字段的字段部分模板:标题,正文) 该模板由我们的许多模板直接和间接继承。

现在在我们的一个子布局中,我们只使用此部分,它是一种更通用的控件,因此我们需要执行:GetCurrentItem<Content>GetCurrentItem<IContent>

我个人觉得GetCurrentItem<IContent>更直观,因为它感觉问:“如果它支持内容部分,请给我当前项目”,其他人感觉更像“如果它是内容,请给我当前项目“(从技术上讲,这是不可能的,因为从不创建内容项)

2 个答案:

答案 0 :(得分:9)

为Glass Mapper配置界面可以达到一些目的。首先,Glass Mapper实际上可以根据您的界面创建动态代理对象。这意味着您实际上可以单独使用基于接口的Glass Mapper,而无需您自己的具体实现。

Mike Edwards describes this here

  

幕后花絮Glass.Sitecore.Mapper mapper会检测到你是谁   使用界面并使用Castle Dynamic Proxies生成   您的应用程序可以使用的具体类。

正如他所指出的,这增加了一些开销,并且确实无法添加额外的逻辑。

The other use is type inference。这在接口的上下文中没有很好地记录,但无论是在调用SitecoreService还是在您的字段属性中,都要求Glass Mapper推断类型。对于此行为,您不需要映射接口字段。请务必在具体类的TemplateId属性中包含SitecoreClass。这应该允许您建模多重继承。

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);

答案 1 :(得分:1)

我发现使用接口建模我的Sitecore模板通常是更好的选择。这允许我在代码中模拟我的模板结构,就像它在Sitecore中一样。例如,

public interface IMyPageTemplate : IBaseTemplate1, IBaseTemplate2 {

}

使用具体类对模板进行建模要困难得多,因为我们通常有许多基本模板。也许值得考虑(虽然,我没有尝试过)接口和具体类的某种组合。也许,像IContent这样的严格基础模板的模板应该被建模为接口,所有可以作为内容创建的模板都应该被建模为具体类。

执行GetCurrentItem<IContent>()之类的操作是有效的。值得注意的是,返回的是一个代理类,它可以提供自己的挑战(取决于你在做什么)。