【问题标题】:Glass Mapper V4 Language Item Fallback, how to make it work with Autofac?Glass Mapper V4 Language Item Fallback,如何使其与 Autofac 一起使用?
【发布时间】:2015-05-21 13:58:52
【问题描述】:

我正在使用带有 Autofac 的 Glass Mapper v4,但无法弄清楚如何使其与 Language Item Fall back 模块一起使用。有创建实现IObjectConstructionTask的类的示例(见下文)

public class FallbackCheckTask : IObjectConstructionTask
{
    public void Execute(ObjectConstructionArgs args)
    {
        if (args.Result == null)
        {
            var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;

            // if the item itself is null, regardless of version, abort
            if (scContext.Item == null)
            {
                args.AbortPipeline();
                return;
            }

            // we could be trying to convert rendering parameters to a glass model, and if so, just return.
            if (String.Compare(scContext.Item.Paths.FullPath, "[orphan]/renderingParameters", true) == 0)
            {
                return;
            }

            // the default glassmapper code would simply abort pipeline if the context items version count for the current langauge was 0
            // but this does not take item fallback into account
            // added here a check on the fallback extension method GetFallbackItem, recursively (for chained fallback)
            // and then if that fallback item is null or it's version count is 0 (and only then) would you go ahead and abort the pipeline
            if (scContext.Item.Versions.Count == 0)
            {
                var fallBackItem = CheckRecursivelyForFallbackItem(scContext.Item);
                if (fallBackItem == null)
                    args.AbortPipeline();
                else if (fallBackItem.Versions.Count == 0)
                    args.AbortPipeline();
                return;
            }
        }
    }

    // in the case of chained fallback, eg fr-CA -> en-CA -> en
    // could be that the middle languages don't have versions either, but DO have a fallback item
    // therefore, must check back further until either a version is found, or there are no more fallback items
    private Item CheckRecursivelyForFallbackItem(Item thisItem)
    {
        var fallBackItem = thisItem.GetFallbackItem();
        if (fallBackItem != null)
        {
            if (fallBackItem.Versions.Count == 0)
                fallBackItem = CheckRecursivelyForFallbackItem(fallBackItem);
        }
        return fallBackItem;
    }
}

然后你注册(在温莎城堡)

public static void CastleConfig(IWindsorContainer container){
            var config = new Config();

            container.Register(
               Component.For<IObjectConstructionTask>().ImplementedBy<FallbackCheckTask>().LifestylePerWebRequest()
              );
          //  config.EnableCaching = false;

            container.Install(new SitecoreInstaller(config));
        }

我正在使用 Autofac,但不知道如何执行与上述相同的操作并确保它以正确的顺序发生。我正在以典型的方式注册我的类型(见下文),但它似乎并没有吸引我的 FallbackCheckTask 类。

 public static void Register()
    {
        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly);

        // register our types
        builder.RegisterType<FallbackCheckTask>().As<IObjectConstructionTask>().InstancePerLifetimeScope();

        // build and set the resolver
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }

如果 glass 不参与获取项目值,我还连接了 Language Item Fallback 并按预期工作。我理解为什么 Glass 没有开箱即用地映射数据,我似乎无法让修复工作。有什么想法吗?

编辑 2015-05-21 19:00

我将GlassMapperScCustom.cs编辑如下:

public static IDependencyResolver CreateResolver(){
        var config = new Glass.Mapper.Sc.Config();
        var resolver = new DependencyResolver(config);

        resolver.ObjectConstructionFactory.Add(() => new FallbackCheckTask());

        return resolver;
    }

现在它调用FallbackCheckTaskExecute 方法,仅当有该项目的版本时,如果没有版本则不调用该方法。此外,如果我启用此任务,无论我做什么,我的测试查询项总是返回为 NULL:

  var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
            var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList();
            var test2 = SitecoreContext.GetCurrentItem<Item>();
            var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");

总而言之,我现在比以前好一点,但是当任务类注册时,所有项目的查询都返回为空,无论它们是否有版本。如前所述,感谢您提供任何帮助。

【问题讨论】:

标签: sitecore autofac glass-mapper


【解决方案1】:

我知道您提到您使用的是VersionCountDisabler,但它看起来像这样吗:

using(new VersionCountDisabler()){

        var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");
        var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList();
        var test2 = SitecoreContext.GetCurrentItem<Item>();
        var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");

}

或者您是否以其他方式禁用它?

我还注意到您的后备代码似乎没有更新 scContent.Item 属性。我认为您需要将其更新为以下内容:

public class FallbackCheckTask : IObjectConstructionTask
{
public void Execute(ObjectConstructionArgs args)
{
    if (args.Result == null)
    {
        var scContext = args.AbstractTypeCreationContext as SitecoreTypeCreationContext;

        // if the item itself is null, regardless of version, abort
        if (scContext.Item == null)
        {
            args.AbortPipeline();
            return;
        }

        // we could be trying to convert rendering parameters to a glass model, and if so, just return.
        if (String.Compare(scContext.Item.Paths.FullPath, "[orphan]/renderingParameters", true) == 0)
        {
            return;
        }

        // the default glassmapper code would simply abort pipeline if the context items version count for the current langauge was 0
        // but this does not take item fallback into account
        // added here a check on the fallback extension method GetFallbackItem, recursively (for chained fallback)
        // and then if that fallback item is null or it's version count is 0 (and only then) would you go ahead and abort the pipeline
        if (scContext.Item.Versions.Count == 0)
        {
            var fallBackItem = CheckRecursivelyForFallbackItem(scContext.Item);
            if (fallBackItem == null)
                args.AbortPipeline();
            else if (fallBackItem.Versions.Count == 0)
                args.AbortPipeline();

            //don't just return but update the scContext.Item to the fallback item
            scContext.Item = fallbackItem;
        }
    }
}

// in the case of chained fallback, eg fr-CA -> en-CA -> en
// could be that the middle languages don't have versions either, but DO have a fallback item
// therefore, must check back further until either a version is found, or there are no more fallback items
private Item CheckRecursivelyForFallbackItem(Item thisItem)
{
    var fallBackItem = thisItem.GetFallbackItem();
    if (fallBackItem != null)
    {
        if (fallBackItem.Versions.Count == 0)
            fallBackItem = CheckRecursivelyForFallbackItem(fallBackItem);
    }
    return fallBackItem;
}
}

【讨论】:

  • 您的更新修复了它!非常感谢,我真的很感激!我有一个问题。是否有更全局的方法来禁用版本计数,或者我是否像您上面所说的那样坚持这样做?
  • 等等……抱歉。它修复了崩溃,但实际上仍然没有为备用语言提取内容。
  • 嗨,这正如我在测试中所期望的那样工作。在这种情况下要考虑的一件事是所有子属性都填充在父项的上下文中。因此,如果您回退“根”项,则子项将以父项的语言而不是用户的原始语言填充。
  • 感谢您的所有帮助,它在 Sitecore 8 rev3 中对我来说似乎无法正常工作。我安装了语言后备和字段后备并使用了您的代码,但仍然没有运气。从图片中取出玻璃,它仍然不会后退。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 2015-05-26
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多