LazyItemEnumerable always loads lazy even with isLazy=false (#79) - Causes empty children lists

44 views
Skip to first unread message

Davy Cool

unread,
Aug 25, 2014, 7:16:41 AM8/25/14
to glass...@googlegroups.com

The LazyItemEnumerable class has a boolean constructor parameter "isLazy" that can be set to false. One would expect the items would be loaded imediatly but this is not the case as the retrieval is specified as a delegate that is used in a Lazy field. This class is used in the ChildrenMapper, EnumerableMapper, ... .
This causes side effects where items are retrieved and mapped to the Glass object in a SecurityDisabler context because the user has no read rights on the item (and child items or items returned by the Query). In the children attribute we specify that this should NOT happen lazy, so we expect the child items to be retrieved and mapped while the root item is cast to Glass within the SecurityDisabler context but this is not the case. So we get an empty collection when we iterate over the items because the current user has no read acces to them.

A possible way to fix is to imediately invoke the Lazy field "_lazyItemList" that contains the delegate to retrieve and map the child items to Glass objects when the constructor argument "isLazy=false".

Our code depends on the Children/SitecoreQuery mapper in a lot of places, so it's crutial for us that when we specify Lazy=false that the retrieval occurs in the SecurityDisablerContext or the context in which we retrieve the glass item/cast to a glass item. Is it possible to fix this and create a new nuget package?

/// <summary>
    /// Initializes a new instance of the <see cref="LazyItemEnumerable{T}"/> class.
    /// </summary>
    /// <param name="getItems">The get items.</param>
    /// <param name="isLazy">if set to <c>true</c> [is lazy].</param>
    /// <param name="inferType">if set to <c>true</c> [infer type].</param>
    /// <param name="service">The service.</param>
    public LazyItemEnumerable(
        Func<IEnumerable<Item>> getItems,
        bool isLazy,
        bool inferType,
        ISitecoreService service
        )
    {
        _getItems = getItems;
        _type = typeof(T);
        _isLazy = isLazy;
        _inferType = inferType;
        _service = service;

        _lazyItemList = new Lazy<IList<T>>(() =>ProcessItems().ToList());
       // If not lazy, we could invoke the _lazyItemList here to force the loading of the items.
    }
Reply all
Reply to author
Forward
0 new messages