Manoj Kumawat
OMVPCommerce Connect 14 Developer (Expert) CertificationCommerce Connect 13 Developer Certification +5
Jun 26, 2019
visibility 6075
star star star star star
(5 votes)

Using ExtendedMetadata from SelectionFactory

Prerequisite - 

This tutorial requires a knowledge of ISelectionFactory.

In this tutorial I would like to share my experience with SelectionFactory features from Episerver.

We had a requirement where an Episerver CMS user should be able to view the options based on certain parameters. Consider the case where you have a multiple options type fields within the CMS those should be fetching their values according to input parameters via attribute. 

Step 1 - Creating an abstract SelectionFactory class

We are going to inherit the Interface ISelectionFactory from EPiServer.Shell.ObjectEditing Assembly and creating our custom LookupSelectionFactory as a service factory.

I would have an additional method AddItems of type virtual to be able to override in derived class (the class which inherits LookupSelectionFactory).

Note that It has two parameteres and one of them is ExtendedMetadata that we are going to use to fetch the values from attribute.

public abstract class LookupSelectionFactory : ISelectionFactory
{
   protected virtual IEnumerable<ISelectItem> AddItems(RestClient client, ExtendedMetadata metadata)
   {
    throw new NotImplementedException();
   }
}

Step 2 - Creating an Attribute class (to input desired parameters)

[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
public class PickListAttribute : System.Attribute
{
	public string AttributeName { get; set; }
	public string AttributeType { get; set; }
}

AttributeTargets.All - Specifies that Attribute can be applied to any application element. Whether it's a constructor, class, delegate, event etc.

AllowMultiple - Gets or sets a Boolean value indicating whether more than once instance of the indicated attribute can be specified for a single program element.

Inhertied - Gets or sets a Boolean value that determines whether the indicated attribute is inherited by derived class and overriding members.

Step 3 - Using factory on Block property

[CultureSpecific]
        [Display(
            Name = "Title Options", Description = "Title Options", GroupName = FormTabGroups.ABOUT_YOU_TAB, Order = 1)]
        [PickListAttribute(AttributeType = "CONTACT", AttributeName = "TITLE")]
        [SelectMany(SelectionFactoryType = typeof(ShowOptionsSelectionFactory))]
        public virtual string TitleOptions { get; set; }

In the next step > create ShowOptionsSelectionFactory that will display the Options in Episerver.

Step 4 - Inheriting abstract factory and reusing it in custom selection factory for our purpose

 public class ShowOptionsSelectionFactory : LookupSelectionFactory
        {
            protected override IEnumerable<ISelectItem> AddItems(RestClient client, ExtendedMetadata metadata)
            {
                List<ISelectItem> items = new List<ISelectItem>();
                try
                {
                    PickListAttribute pickListAttribute = (PickListAttribute)metadata.Attributes.FirstOrDefault(c => c is PickListAttribute);
                    string name = pickListAttribute.AttributeName;
                    string type = pickListAttribute.AttributeType;

                  items.Add(new SelectItem()
                   {
                     Value = type,
                     Text = name,
                   });
                }
                catch (Exception ex)
                {
                    //catch the exception here
                }

                return items;

            }
        }

The line above picks the attribute of type PickListAttribute amongst other Attributes on the same property - [CultureSpecific], [Display], [SelectMany] with the help of metadata parameter.

(PickListAttribute)metadata.Attributes.FirstOrDefault(c => c is PickListAttribute) 

The metadata keeps the Attributes information along with it that you can pull based on your needs.

For instance if you want to fetch the values for Display attribute being used on the property TitleOptions, Then you can query within Attributes property from metadata and cast it like this - 

DisplayAttribute crmPickListAttribute = (DisplayAttribute)metadata.Attributes.FirstOrDefault(c => c is DisplayAttribute);

Enjoy your day!

Jun 26, 2019

Comments

error Please login to comment.
Latest blogs
Surviving a Dirty Feed. Part 3: Error Handling and Event Batching

Committing a 250,000-row Optimizely catalog import row by row, returning a per-row failure report, and coalescing catalog events into one per batch.

Stanisław Szołkowski | Oct 16, 2026 |

Building UI Extensions for Optimizely SaaS CMS

Introduction Developers have been extending the functionality of Optimizely PaaS CMS for years using addons built in C# and deployed as NuGet...

Mark Stott | Oct 15, 2026

Cheapskate AI Translator: Because Translation Should Not Require a Second Mortgage

There is a particular kind of software project that begins with a detailed architecture document, a product roadmap, and a carefully assembled...

Linh Doan Cuu | Oct 15, 2026

Computed Fields in CMS 13 Content Contracts with Optimizely Graph

Content Contracts in Optimizely CMS 13 allow different content types to share a common structure when querying Optimizely Graph. But what if the...

Mardy | Oct 14, 2026