Last active
September 29, 2016 13:20
-
-
Save jstemerdink/4af1bd14f06aa7f2ee6f to your computer and use it in GitHub Desktop.
Use an attribute to create facets for an EPiServer Find query
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Facet(1, FacetType.TermsFacetFor)] | |
public virtual string TermsFacetExample { get; set; } | |
IClient searchManager = Client.CreateFromConfig(); | |
ITypeSearch<StandardPage> queryTest = searchManager.Search<StandardPage>().For("test"); | |
queryTest = queryTest.AddFacets(); | |
IContentResult<StandardPage> results = queryTest.GetContentResult(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Class FacetAttribute. This class cannot be inherited. | |
/// </summary> | |
[AttributeUsage(AttributeTargets.Property)] | |
public sealed class FacetAttribute : Attribute | |
{ | |
/// <summary> | |
/// Initializes a new instance of the <see cref="FacetAttribute"/> class. | |
/// </summary> | |
/// <param name="index">The index.</param> | |
/// <param name="facetType">Type of the facet.</param> | |
public FacetAttribute(int index, FacetType facetType) | |
{ | |
this.Index = index; | |
this.FacetType = facetType; | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="FacetAttribute"/> class. | |
/// </summary> | |
/// <param name="index">The index.</param> | |
public FacetAttribute(int index) | |
{ | |
this.Index = index; | |
this.FacetType = FacetType.TermsFacetFor; | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="FacetAttribute"/> class. | |
/// </summary> | |
public FacetAttribute() | |
{ | |
this.Index = 0; | |
this.FacetType = FacetType.TermsFacetFor; | |
} | |
#region Public Properties | |
/// <summary> | |
/// Gets the index. | |
/// </summary> | |
/// <value>The index.</value> | |
public int Index { get; } | |
/// <summary> | |
/// Gets the type of the facet. | |
/// </summary> | |
/// <value>The type of the facet.</value> | |
public FacetType FacetType { get; } | |
/// <summary> | |
/// Gets a value indicating whether the property is used as a facet in EPiServer Find. | |
/// </summary> | |
/// <value><c>true</c> if [used as a facet in EPiServer Find]; otherwise, <c>false</c>.</value> | |
public static bool Facet | |
{ | |
get | |
{ | |
return true; | |
} | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Enum FacetType | |
/// </summary> | |
public enum FacetType | |
{ | |
TermsFacetForWordsIn, | |
TermsFacetFor | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Class FindExtensions. | |
/// </summary> | |
public static class FindExtensions | |
{ | |
/// <summary> | |
/// Adds facets to a Find query base on an attribute. | |
/// </summary> | |
/// <typeparam name="T">The content type to add the facets for.</typeparam> | |
/// <param name="query">The query.</param> | |
/// <returns>ITypeSearch<T>.</returns> | |
public static ITypeSearch<T> AddFacets<T>(this ITypeSearch<T> query) where T : IContent | |
{ | |
foreach (PropertyInfo propertyInfo in GetPropertiesSortedByIndex<T>()) | |
{ | |
FacetAttribute facetAttribute = Attribute.GetCustomAttribute(propertyInfo, typeof(FacetAttribute)) as FacetAttribute; | |
if (facetAttribute == null) | |
{ | |
continue; | |
} | |
ParameterExpression expParam = Expression.Parameter(typeof(T), "x"); | |
MemberExpression expProp = Expression.Property(expParam, propertyInfo); | |
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), propertyInfo.PropertyType); | |
dynamic expression = Expression.Lambda(delegateType, expProp, expParam); | |
try | |
{ | |
switch (facetAttribute.FacetType) | |
{ | |
case FacetType.TermsFacetFor: | |
query = TypeSearchExtensions.TermsFacetFor(query, expression); | |
break; | |
case FacetType.TermsFacetForWordsIn: | |
query = TypeSearchExtensions.TermsFacetForWordsIn(query, expression); | |
break; | |
default: | |
query = TypeSearchExtensions.TermsFacetFor(query, expression); | |
break; | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
return query; | |
} | |
/// <summary> | |
/// Gets the properties that has the FacetAttribute sorted by the index. | |
/// </summary> | |
/// <typeparam name="T">The type to get the properties for.</typeparam> | |
/// <returns>IEnumerable<PropertyInfo>.</returns> | |
private static IEnumerable<PropertyInfo> GetPropertiesSortedByIndex<T>() where T : IContent | |
{ | |
PropertyInfo[] allProperties = typeof(T) | |
.GetProperties() | |
.Where(HasAttribute<FacetAttribute>) | |
.Select(x => new | |
{ | |
Property = x, | |
Attribute = (FacetAttribute)Attribute.GetCustomAttribute(x, typeof(FacetAttribute), true) | |
}) | |
.OrderBy(x => x.Attribute != null ? x.Attribute.Index : -1) | |
.Select(x => x.Property) | |
.ToArray(); | |
return allProperties; | |
} | |
/// <summary> | |
/// Determines whether the specified property has the specified attribute. | |
/// </summary> | |
/// <typeparam name="T">The attribute type.</typeparam> | |
/// <param name="propertyInfo">The propertyInfo.</param> | |
/// <returns><c>true</c> if the specified self has attribute; otherwise, <c>false</c>.</returns> | |
private static bool HasAttribute<T>(PropertyInfo propertyInfo) where T : Attribute | |
{ | |
T attr = default(T); | |
try | |
{ | |
attr = (T)Attribute.GetCustomAttribute(propertyInfo, typeof(T)); | |
} | |
catch (Exception) | |
{ | |
} | |
return attr != null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment