Skip to content

Commit

Permalink
Merge pull request #2 from jstemerdink/master
Browse files Browse the repository at this point in the history
Updated to latest version of Commerce
  • Loading branch information
jonasbergqvist authored Apr 30, 2019
2 parents 3834e41 + 2a0d362 commit 28090ec
Show file tree
Hide file tree
Showing 85 changed files with 5,219 additions and 2,177 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -1007,3 +1007,4 @@
/StarterDemoB2CSite.episerverdata
/StarterDemoDepartmental.zip
/StarterDemoDepartmental/Catalog.xml
.vs/
Binary file removed BrilliantCut.Core.0.2.1.nupkg
Binary file not shown.
Binary file added BrilliantCut.Core.1.0.0.nupkg
Binary file not shown.
14 changes: 7 additions & 7 deletions BrilliantCut.Core.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package >
<metadata>
<id>BrilliantCut.Core</id>
<version>0.2.1</version>
<version>1.0.0</version>
<title>Brilliant Cut Core</title>
<authors>Jonas Bergqvist</authors>
<owners>Jonas Bergqvist</owners>
Expand All @@ -13,15 +13,15 @@
<description>Facet support in commerce UI</description>
<releaseNotes></releaseNotes>
<copyright>Copyright Jonas Berqvist 2015</copyright>
<tags></tags>
<tags>EPiServer, Search, Commerce, UI</tags>
<dependencies>
<dependency id="EPiServer.Commerce.Core" version="[8,10)" />
<dependency id="EPiServer.Commerce.UI" version="[8,10)" />
<!--dependency id="EPiServer.Find.Commerce" version="[8,10)" /-->
<dependency id="Newtonsoft.Json" version="[6,9)" />
<dependency id="EPiServer.Commerce.Core" version="[11,13)" />
<dependency id="EPiServer.Commerce.UI" version="[11,13)" />
<dependency id="EPiServer.Find.Commerce" version="[11,13)" />
<dependency id="Newtonsoft.Json" version="[9,12)" />
</dependencies>
</metadata>
<files>
<file src="BrilliantCut.Core\bin\debug\BrilliantCut.Core.dll" target="lib\net45" />
<file src="BrilliantCut.Core\bin\release\BrilliantCut.Core.dll" target="lib\net461" />
</files>
</package>
157 changes: 104 additions & 53 deletions BrilliantCut.Core/Activator.cs
Original file line number Diff line number Diff line change
@@ -1,83 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using EPiServer;
using EPiServer.Framework.Cache;
using EPiServer.ServiceLocation;
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Activator.cs" company="Jonas Bergqvist">
// Copyright © 2019 Jonas Bergqvist.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace BrilliantCut.Core
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

using EPiServer;
using EPiServer.Framework.Cache;
using EPiServer.ServiceLocation;

/// <summary>
/// Creates an instance of <see cref="T"/>.
/// Creates an instance of the specified type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T">The type to activate</typeparam>
public class Activator<T>
{
private IObjectInstanceCache _objectInstanceCache;
/// <summary>
/// The object instance cache
/// </summary>
private IObjectInstanceCache objectInstanceCache;

/// <summary>
/// Delegate ObjectActivator
/// </summary>
/// <param name="args">The arguments.</param>
/// <returns>An instance of T.</returns>
private delegate T ObjectActivator(params object[] args);

/// <summary>
/// Gets or sets the object instance cache.
/// </summary>
/// <value>The object instance cache.</value>
private IObjectInstanceCache ObjectInstanceCache
{
get
{
return _objectInstanceCache ?? (_objectInstanceCache = ServiceLocator.Current.GetInstance<IObjectInstanceCache>());
return this.objectInstanceCache
?? (this.objectInstanceCache = ServiceLocator.Current.GetInstance<IObjectInstanceCache>());
}

set
{
_objectInstanceCache = value;
this.objectInstanceCache = value;
}

}

/// <summary>
/// Creates an instance of the <see cref="T"/>.
/// Creates an instance of the <typeparamref name="T"> name="T">The type to activate</typeparamref>.
/// </summary>
/// <param name="args">Arguments, used for constructor creation, and for creating a generic type</param>
/// <returns>The requested <see cref="T"/>.</returns>
/// <returns>The requested <typeparamref name="T"> name="T">The type to activate</typeparamref>.</returns>
/// <exception cref="T:System.Exception">A delegate callback throws an exception.</exception>
/// <remarks>The supports generic arguments.</remarks>
public T Activate(params object[] args)
{
return Activate(typeof(T), args);
return this.Activate(typeof(T), constructorArguments: args);
}

/// <summary>
/// Creates an instance of the <paramref name="type"/>.
/// Creates an instance of the <paramref name="type" />.
/// </summary>
/// <param name="type">The type to create.</param>
/// <param name="constructorArguments">Arguments, used for constructor creation.</param>
/// <returns>The requested <paramref name="type"/>.</returns>
/// <returns>The requested <paramref name="type" />.</returns>
/// <exception cref="T:System.Exception">A delegate callback throws an exception.</exception>
/// <exception cref="T:System.ArgumentNullException"><paramref name="constructorArguments" /> is <see langword="null" />.</exception>
/// <remarks>The supports generic arguments.</remarks>
public T Activate(Type type, params object[] constructorArguments)
{
var argumentTypes = constructorArguments
.Select(x => x != null ? x.GetOriginalType() : typeof(object))
Type[] argumentTypes = constructorArguments.Select(x => x != null ? x.GetOriginalType() : typeof(object))
.ToArray();

var cacheKey = String.Concat(type.GetHashCode(), "#", String.Join(":", argumentTypes.Select(x => x.GetHashCode())));
var objectActivator = ObjectInstanceCache.ReadThrough(cacheKey, () =>
{
var finalType = type.IsGenericTypeDefinition ? type.MakeGenericType(argumentTypes) : type;
return GetObjectActivator(finalType, argumentTypes);
}, null);
string cacheKey = string.Concat(
type.GetHashCode(),
"#",
string.Join(":", argumentTypes.Select(x => x.GetHashCode())));

return objectActivator(constructorArguments);
ObjectActivator objectActivator = this.ObjectInstanceCache.ReadThrough(
key: cacheKey,
readValue: () =>
{
Type finalType = type.IsGenericTypeDefinition
? type.MakeGenericType(typeArguments: argumentTypes)
: type;
return GetObjectActivator(type: finalType, constructorArgumentTypes: argumentTypes);
},
readStrategy: ReadStrategy.Wait);

return objectActivator(args: constructorArguments);
}

/// <summary>
/// Gets the objector activator delegate, that will be used to create the requested object.
/// Creates <see cref="ObjectActivator" />, that will be used to create the requested type.
/// </summary>
/// <param name="constructorArgumentTypes">The constructor information.</param>
/// <param name="type">The type to activate</param>
/// <returns>The delegate with instructions to create the specified type.</returns>
private static ObjectActivator GetObjectActivator(Type type, Type[] constructorArgumentTypes)
/// <param name="constructorInfo">The constructor information.</param>
/// <param name="constructorTypeExpressions">Expressions for the constructor types.</param>
/// <param name="delegateParameterExpression">The delegate parameter expression.</param>
/// <returns>The <see cref="ObjectActivator" /></returns>
private static ObjectActivator CreateDelegate(
ConstructorInfo constructorInfo,
IEnumerable<Expression> constructorTypeExpressions,
ParameterExpression delegateParameterExpression)
{
var constructorInfo = type.GetConstructor(constructorArgumentTypes);
var delegateParameterExpression = Expression.Parameter(typeof(object[]), "args");
NewExpression constructorExpression = Expression.New(
constructor: constructorInfo,
arguments: constructorTypeExpressions);
LambdaExpression lambdaExpression = Expression.Lambda(
typeof(ObjectActivator),
constructorExpression,
delegateParameterExpression);

var typeExpressions = CreateTypeExpressions(constructorArgumentTypes, delegateParameterExpression).ToList();
return CreateDelegate(constructorInfo, typeExpressions, delegateParameterExpression);
return (ObjectActivator)lambdaExpression.Compile();
}

/// <summary>
Expand All @@ -86,33 +126,44 @@ private static ObjectActivator GetObjectActivator(Type type, Type[] constructorA
/// <param name="constructorArgumentTypes">The constructor argument types.</param>
/// <param name="delegateParameterExpression">The expression for the delegate parameter.</param>
/// <returns>Expressions for the constructor arguments.</returns>
private static IEnumerable<Expression> CreateTypeExpressions(Type[] constructorArgumentTypes, Expression delegateParameterExpression)
private static IEnumerable<Expression> CreateTypeExpressions(
Type[] constructorArgumentTypes,
Expression delegateParameterExpression)
{
for (var i = 0; i < constructorArgumentTypes.Length; i++)
for (int i = 0; i < constructorArgumentTypes.Length; i++)
{
var paramType = constructorArgumentTypes[i];
Type paramType = constructorArgumentTypes[i];

var indexExpression = Expression.Constant(i);
var paramAccessorExpression = Expression.ArrayIndex(delegateParameterExpression, indexExpression);
var paramCastExpression = Expression.Convert(paramAccessorExpression, paramType);
ConstantExpression indexExpression = Expression.Constant(value: i);
BinaryExpression paramAccessorExpression = Expression.ArrayIndex(
array: delegateParameterExpression,
index: indexExpression);
UnaryExpression paramCastExpression = Expression.Convert(
expression: paramAccessorExpression,
type: paramType);

yield return paramCastExpression;
}
}

/// <summary>
/// Creates <see cref="ObjectActivator"/>, that will be used to create the requested type.
/// Gets the objector activator delegate, that will be used to create the requested object.
/// </summary>
/// <param name="constructorInfo">The constructor information.</param>
/// <param name="constructorTypeExpressions">Expressions for the constructor types.</param>
/// <param name="delegateParameterExpression">The delegate parameter expression.</param>
/// <returns>The <see cref="ObjectActivator"/></returns>
private static ObjectActivator CreateDelegate(ConstructorInfo constructorInfo, IEnumerable<Expression> constructorTypeExpressions, ParameterExpression delegateParameterExpression)
/// <param name="type">The type to activate</param>
/// <param name="constructorArgumentTypes">The constructor information.</param>
/// <returns>The delegate with instructions to create the specified type.</returns>
private static ObjectActivator GetObjectActivator(Type type, Type[] constructorArgumentTypes)
{
var constructorExpression = Expression.New(constructorInfo, constructorTypeExpressions);
var lambdaExpression = Expression.Lambda(typeof(ObjectActivator), constructorExpression, delegateParameterExpression);
ConstructorInfo constructorInfo = type.GetConstructor(types: constructorArgumentTypes);
ParameterExpression delegateParameterExpression = Expression.Parameter(typeof(object[]), "args");

return (ObjectActivator)lambdaExpression.Compile();
List<Expression> typeExpressions = CreateTypeExpressions(
constructorArgumentTypes: constructorArgumentTypes,
delegateParameterExpression: delegateParameterExpression).ToList();
return CreateDelegate(
constructorInfo: constructorInfo,
constructorTypeExpressions: typeExpressions,
delegateParameterExpression: delegateParameterExpression);
}
}
}
}
Loading

0 comments on commit 28090ec

Please sign in to comment.