我们是Glass mapper的新手,想在我们的Sitecore项目中使用它。在查看教程时,我们注意到没有深入的示例说明如何设置Sitecore允许的深度继承。在浏览网页时,我们注意到有人在界面上放置属性,另一方面有人将属性放在具体的类上。这些例子都没有解释他们这样做的好理由,但是给我们留下了一个问题:这是正确的用法,做一个或另一个的影响是什么?
请考虑以下事项:
模板:内容(添加2个简单字段的字段部分模板:标题,正文) 该模板由我们的许多模板直接和间接继承。
现在在我们的一个子布局中,我们只使用此部分,它是一种更通用的控件,因此我们需要执行:GetCurrentItem<Content>
或GetCurrentItem<IContent>
。
我个人觉得GetCurrentItem<IContent>
更直观,因为它感觉问:“如果它支持内容部分,请给我当前项目”,其他人感觉更像“如果它是内容,请给我当前项目“(从技术上讲,这是不可能的,因为从不创建内容项)
答案 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>()
之类的操作是有效的。值得注意的是,返回的是一个代理类,它可以提供自己的挑战(取决于你在做什么)。