Views: 1187
Number of votes: 4
Average rating:

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

Please login to comment.