Glass Mapper V4 Language Item Fallback, как заставить его работать с Autofac?

Я использую Glass Mapper v4 с Autofac и не могу понять, как заставить его работать с модулем возврата языковых элементов. Есть примеры создания класса, реализующего 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;
    }
}

Затем вы регистрируетесь (в Castle Windsor)

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 не отображает данные из коробки, я просто не могу заставить работать исправление. Есть предположения?

ИЗМЕНИТЬ 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;
    }

И теперь он вызывает метод Execute для FallbackCheckTask, только если есть версия элемента, если версии нет, метод не вызывается. Кроме того, независимо от того, что я делаю, если я включаю эту задачу, мои элементы тестового запроса всегда возвращаются как 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}");

Подводя итог, можно сказать, что сейчас мне немного лучше, чем было раньше, но когда класс задач зарегистрирован, запросы возвращаются как нулевые для всех элементов, независимо от того, есть у них версия или нет. Как упоминалось ранее, любая помощь приветствуется.


person mluker    schedule 21.05.2015    source источник
comment
Длинный выстрел - вы отключили подсчет версий?   -  person Ian Graham    schedule 23.05.2015
comment
Да, я отключил подсчет версий. Спасибо.   -  person mluker    schedule 26.05.2015
comment
вам, вероятно, следует поместить Edit в качестве ответа. Ответить на свой вопрос вполне приемлемо   -  person Liam    schedule 03.11.2015


Ответы (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;
}
}
person Michael Edwards    schedule 29.05.2015
comment
Ваши обновления исправили это! Большое спасибо, я очень ценю это! У меня есть один вопрос. Есть ли более глобальный способ отключить подсчет версий, или я застрял, делая это, как вы выше? - person mluker; 29.05.2015
comment
Подожди... извини. Это устранило его сбой, но на самом деле он все еще не извлекает содержимое для резервного языка. - person mluker; 29.05.2015
comment
Привет, это работает так, как я ожидаю в своих тестах. В этом сценарии следует учитывать, что все подсвойства заполняются в контексте родительского элемента. Поэтому, если вы отмените корневой элемент, то дочерние элементы будут заполнены на языке родителя, а не на исходном языке пользователя. - person Michael Edwards; 01.06.2015
comment
Спасибо за всю вашу помощь, похоже, у меня это не работает должным образом в Sitecore 8 rev3. Я установил резервную копию языка и резервную копию поля и использовал ваш код, и все равно не повезло. Убрав стекло с картинки, оно все равно не вернется. Спасибо еще раз. - person mluker; 04.06.2015
comment
Я тестировал на 7.5, кажется странным, что это не сработает для более поздней версии. Я создал собственный метод для резервного языка только для проверки. - person Michael Edwards; 04.06.2015
comment
Я думаю, что у меня неправильная версия Sitecore.Sharedsource.PartialLanguageFallabck.dll. Проблема в методе public static Language GetFallbackLanguage(this Item langItem) вызов var fallbackLangName = langItem[Constants.FieldIds.FallbackLanguage]; возвращает ноль. - person mluker; 04.06.2015
comment
Оказывается, если я не реализую IObjectConstructionTask, он работает до тех пор, пока я оборачиваю все вызовы данных с использованием (VersionCountDisabler()). Это становится утомительным, есть ли лучший способ? Я безуспешно пытался добавить его в Global.asax (Sitecore.Context.Items[Disable] = new VersionCountDisabler(); ) - person mluker; 04.06.2015
comment
Я сделал несколько заметок по этому поводу: glass.lu/Mapper/Sc/Documentation/VersionCountDisabler< /а> - person Michael Edwards; 22.06.2015