November Happy Hour will be moved to Thursday December 5th.

Prevent Episerver from caching SelectionFactory

Vote:
 

Greetings.

I think I am having an issue with Episerver's caching of a SelectionFactory's ISelectItem objects. I have a block which consists of a PropertyList property. Moreover, T contains a property that is a backed by a SelectionFactory.

Usually when I use SelectionFactory in Episerver, the GetSelections() function is invoked every time the owner content is loaded (the page or block that contains the respective property). This does not seem to be the case for custom objects used within PropertyLists. In this case, the "owner content" of the SelectionFactory is a POCO and appears to be created once and then put into the cache.


To clarify my issue, the folloing code might help:

[PropertyDefinitionTypePlugIn]
public class TableFiltersPropertyList : PropertyListBase
{
}

public class TableFilter
{
    [SelectOne(SelectionFactoryType = typeof(TableColumnSelectionFactory))]
    public string Column { get; set; }
    
    public string Value { get; set; }
}

public class TableColumnSelectionFactory : ISelectionFactory
{
    public IEnumerable GetSelections(ExtendedMetadata metadata)
    {
      switch (GetTableNameFromUserCookie())
      {
        case "Economy Table":
            // return economy related options
            break;
        case "Foods Table":
            // return foods related options
            break;
        case "Sports Results Table":
            // return sports related options
            break;
      }
    
      // I need this to return different options based on the value of SelectedTable 
      // property in the TableBlock block.
      // I attempted to solve this by setting a global static variable/browser cookie
      // from the TableBlock's controller. This works to some extent, but caching 
      // prevents me from sticking to this solution.
    }
}

public class TableBlock : SiteBlockData
{
    [Required]
    public virtual string SelectedTable { get; set; }

    [EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor))]
    public virtual IList Filters { get; set; }
}

When the user creates an instance of TableBlock, he gives it a name, for instance "Economy Table". He then proceeds to add filters to this table's columns through the block's Filters property. The underlying POCO here (TableFilter) has a Column property that shows a dropdown based on values returned from TableColumnSelectionFactory.GetSelections(). I want my SelectionFactory to return different values here for the "Economy Table" than for say the "Sports Results Table".

My problem occurs when the user creates another instance of TableBlock. This time he names the block "Foods Table". For some reason, when the user attempts to add filters to the "Foods Table", the options he can choose from is related to the "Economy Table". This seems to be because the TableFilter POCO is cached by Episerver and the options for the Column property are still same ones that were returned from TableColumnSelectionFactory.GetSelections() the first time it was called.

I hope this made sense, if not I will be happy to provide further information.

Can anyone help me make Episerver stop caching this particular object or point me in the direction how to solve this problem?

Thanks!

#178912
Edited, May 26, 2017 9:18
Vote:
 

I was able to work around this issue by using a SelectionQuery instead of SelectionFactory for the TableFilter.Column property.

For the record:

[ServiceConfiguration(typeof(ISelectionQuery))]
public class TableColumnSelectionQuery : ISelectionQuery
{
    public ISelectItem GetItemByValue(string value)
    {
        return TableHelper.GetCurrentTableColumns().FirstOrDefault(column => column.Value.Equals(value));
    }

    public IEnumerable<ISelectItem> GetItems(string query)
    {
        return TableHelper.GetCurrentTableColumns()
            .Where(column => column.Text.StartsWith(query, StringComparison.OrdinalIgnoreCase));
    }
}

public class TableFilter
{
    [AutoSuggestSelection(typeof(TableColumnSelectionQuery))]
    public string Column { get; set; }

    public string Value { get; set; }

}

Using this approach GetItems() on the TableColumnSelectionQuery is called whenever the user interacts with the drop down. At this point I can look up which table the user is working with and provide the relevant list of columns. 

#178927
May 26, 2017 14:14
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.