【问题标题】:Sitecore Glass Mapper: Attributes on interfaces or concrete classes?Sitecore Glass Mapper:接口或具体类的属性?
【发布时间】:2013-04-03 09:39:55
【问题描述】:

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

考虑以下几点:

模板:内容(这是一个添加 2 个简单字段的字段部分模板:标题、正文) 我们的许多模板都直接和间接地继承了这个模板。

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

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

【问题讨论】:

    标签: sitecore glass-mapper


    【解决方案1】:

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

    Mike Edwards describes this here.

    Glass.Sitecore.Mapper 映射器检测到您在幕后 使用接口并使用 Castle Dynamic Proxies 生成 您的应用程序可以使用的具体类。

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

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

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

    【讨论】:

    • 谢谢,这就是我要找的解释。我希望将来能更好地记录推断类型功能。
    • 您可以使用扩展方法为接口添加额外的逻辑。当然,这并不理想。
    • 第一个链接坏了,不知道有没有新的链接?
    【解决方案2】:

    我发现使用接口对我的 Sitecore 模板进行建模通常是更好的选择。这使我可以像在 Sitecore 中一样在代码中对模板结构进行建模。例如,

    public interface IMyPageTemplate : IBaseTemplate1, IBaseTemplate2 {
    
    }
    

    用具体的类来建模我们的模板要困难得多,因为我们通常有许多基本模板。也许值得考虑(尽管我没有尝试过)某种接口和具体类的组合。也许,像IContent 这样严格意义上的基本模板的模板应该建模为接口,所有可以创建为内容的模板都应该建模为具体的类。

    GetCurrentItem&lt;IContent&gt;() 这样的操作是有效的。值得注意的是,返回的是一个代理类,它可以提供自己的挑战(取决于你在做什么)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      相关资源
      最近更新 更多