Sporadic LifetimeScope issues

Topics: Customizing Orchard, Writing modules
Nov 29, 2013 at 6:52 AM
Edited Nov 29, 2013 at 6:55 AM
Crossposted: http://stackoverflow.com/questions/20279989/sporadic-lifetimescope-issues

Sometimes, I get this error:
"Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed." when querying some Content Items.

This is my function that builds the items:
protected IEnumerable<ContentItem> GetResources(string[] productFilters, string[] topicFilters, string[] techLevelFilters)
        {                  
            var cacheKey = BuildCacheKey(productFilters, topicFilters, techLevelFilters);
            var resourceItems = ContentManager.Query().ForType("Resource").ForVersion(VersionOptions.Published).List();

            if (productFilters != null && productFilters.Any())
            {
                resourceItems = resourceItems.Where(r => productFilters.Contains(GetTaxonomyFieldValue(r, productTaxonomy)));
            }

            if (topicFilters != null && topicFilters.Any())
            {
                resourceItems = resourceItems.Where(r => topicFilters.Contains(GetTaxonomyFieldValue(r, topicTaxonomy)));
            }

            if (techLevelFilters != null && techLevelFilters.Any())
            {
                resourceItems = resourceItems.Where(r => techLevelFilters.Contains(GetTaxonomyFieldValue(r, techLevelTaxonomy)));
            }

            return _cacheManager.Get(cacheKey, ctx =>
            {
                ctx.Monitor(_clock.When(TimeSpan.FromMinutes(CacheTime)));
                return resourceItems;
            });
        }
This is part of the function that calls the one above, which at times shows the error:
string[] newProductFilters = GetProductFilters(0);
            if (newProductFilters != null && newProductFilters.Any())
            {
                productFilters = productFilters.Concat(newProductFilters).ToArray();
            }     

            var resourceItems = GetResources(productFilters, topicFilters, techLevelFilters);
It happens sporadically and I can't really find a cause of the issue. Any piece of advise or information would be highly appreciated. Thanks!
Developer
Nov 29, 2013 at 10:48 PM
Perhaps the cache holds on to the query? Perhaps try and return a projected list from your cache lambda, like so:
return _cacheManager.Get(cacheKey, ctx =>
{
      ctx.Monitor(_clock.When(TimeSpan.FromMinutes(CacheTime)));
      return resourceItems.ToList(); // Project to an in-memory list, which will be cached instead of the deferred query.
});
Dec 4, 2013 at 9:46 PM
Yes, that fixed it. Thanks @sfmskywalker!
Coordinator
Dec 4, 2013 at 9:55 PM
Still bad, you should not cache results from queries, they are linked to their NHibernate session. Please prefer your custom DTO for that (call it view model if you prefer)
Developer
Dec 4, 2013 at 10:37 PM
Yes, Sébastien is right. I didn't realize we're talking about content items.