diff --git a/src/Shared/ActivatorUtilities/ActivatorUtilities.cs b/src/Shared/ActivatorUtilities/ActivatorUtilities.cs
new file mode 100644
index 0000000000..e2553ced1a
--- /dev/null
+++ b/src/Shared/ActivatorUtilities/ActivatorUtilities.cs
@@ -0,0 +1,429 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Runtime.ExceptionServices;
+
+#if ActivatorUtilities_In_DependencyInjection
+using Microsoft.Extensions.Internal;
+
+namespace Microsoft.Extensions.DependencyInjection
+#else
+namespace Microsoft.Extensions.Internal
+#endif
+{
+ ///
+ /// Helper code for the various activator services.
+ ///
+
+#if ActivatorUtilities_In_DependencyInjection
+ public
+#else
+ // Do not take a dependency on this class unless you are explicitly trying to avoid taking a
+ // dependency on Microsoft.AspNetCore.DependencyInjection.Abstractions.
+ internal
+#endif
+ static class ActivatorUtilities
+ {
+ private static readonly MethodInfo GetServiceInfo =
+ GetMethodInfo>((sp, t, r, c) => GetService(sp, t, r, c));
+
+ ///
+ /// Instantiate a type with constructor arguments provided directly and/or from an .
+ ///
+ /// The service provider used to resolve dependencies
+ /// The type to activate
+ /// Constructor arguments not provided by the .
+ /// An activated object of type instanceType
+ public static object CreateInstance(IServiceProvider provider, Type instanceType, params object[] parameters)
+ {
+ int bestLength = -1;
+ var seenPreferred = false;
+
+ ConstructorMatcher bestMatcher = null;
+
+ if (!instanceType.GetTypeInfo().IsAbstract)
+ {
+ foreach (var constructor in instanceType
+ .GetTypeInfo()
+ .DeclaredConstructors
+ .Where(c => !c.IsStatic && c.IsPublic))
+ {
+ var matcher = new ConstructorMatcher(constructor);
+ var isPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false);
+ var length = matcher.Match(parameters);
+
+ if (isPreferred)
+ {
+ if (seenPreferred)
+ {
+ ThrowMultipleCtorsMarkedWithAttributeException();
+ }
+
+ if (length == -1)
+ {
+ ThrowMarkedCtorDoesNotTakeAllProvidedArguments();
+ }
+ }
+
+ if (isPreferred || bestLength < length)
+ {
+ bestLength = length;
+ bestMatcher = matcher;
+ }
+
+ seenPreferred |= isPreferred;
+ }
+ }
+
+ if (bestMatcher == null)
+ {
+ var message = $"A suitable constructor for type '{instanceType}' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.";
+ throw new InvalidOperationException(message);
+ }
+
+ return bestMatcher.CreateInstance(provider);
+ }
+
+ ///
+ /// Create a delegate that will instantiate a type with constructor arguments provided directly
+ /// and/or from an .
+ ///
+ /// The type to activate
+ ///
+ /// The types of objects, in order, that will be passed to the returned function as its second parameter
+ ///
+ ///
+ /// A factory that will instantiate instanceType using an
+ /// and an argument array containing objects matching the types defined in argumentTypes
+ ///
+ public static ObjectFactory CreateFactory(Type instanceType, Type[] argumentTypes)
+ {
+ FindApplicableConstructor(instanceType, argumentTypes, out ConstructorInfo constructor, out int?[] parameterMap);
+
+ var provider = Expression.Parameter(typeof(IServiceProvider), "provider");
+ var argumentArray = Expression.Parameter(typeof(object[]), "argumentArray");
+ var factoryExpressionBody = BuildFactoryExpression(constructor, parameterMap, provider, argumentArray);
+
+ var factoryLamda = Expression.Lambda>(
+ factoryExpressionBody, provider, argumentArray);
+
+ var result = factoryLamda.Compile();
+ return result.Invoke;
+ }
+
+ ///
+ /// Instantiate a type with constructor arguments provided directly and/or from an .
+ ///
+ /// The type to activate
+ /// The service provider used to resolve dependencies
+ /// Constructor arguments not provided by the .
+ /// An activated object of type T
+ public static T CreateInstance(IServiceProvider provider, params object[] parameters)
+ {
+ return (T)CreateInstance(provider, typeof(T), parameters);
+ }
+
+
+ ///
+ /// Retrieve an instance of the given type from the service provider. If one is not found then instantiate it directly.
+ ///
+ /// The type of the service
+ /// The service provider used to resolve dependencies
+ /// The resolved service or created instance
+ public static T GetServiceOrCreateInstance(IServiceProvider provider)
+ {
+ return (T)GetServiceOrCreateInstance(provider, typeof(T));
+ }
+
+ ///
+ /// Retrieve an instance of the given type from the service provider. If one is not found then instantiate it directly.
+ ///
+ /// The service provider
+ /// The type of the service
+ /// The resolved service or created instance
+ public static object GetServiceOrCreateInstance(IServiceProvider provider, Type type)
+ {
+ return provider.GetService(type) ?? CreateInstance(provider, type);
+ }
+
+ private static MethodInfo GetMethodInfo(Expression expr)
+ {
+ var mc = (MethodCallExpression)expr.Body;
+ return mc.Method;
+ }
+
+ private static object GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
+ {
+ var service = sp.GetService(type);
+ if (service == null && !isDefaultParameterRequired)
+ {
+ var message = $"Unable to resolve service for type '{type}' while attempting to activate '{requiredBy}'.";
+ throw new InvalidOperationException(message);
+ }
+ return service;
+ }
+
+ private static Expression BuildFactoryExpression(
+ ConstructorInfo constructor,
+ int?[] parameterMap,
+ Expression serviceProvider,
+ Expression factoryArgumentArray)
+ {
+ var constructorParameters = constructor.GetParameters();
+ var constructorArguments = new Expression[constructorParameters.Length];
+
+ for (var i = 0; i < constructorParameters.Length; i++)
+ {
+ var constructorParameter = constructorParameters[i];
+ var parameterType = constructorParameter.ParameterType;
+ var hasDefaultValue = ParameterDefaultValue.TryGetDefaultValue(constructorParameter, out var defaultValue);
+
+ if (parameterMap[i] != null)
+ {
+ constructorArguments[i] = Expression.ArrayAccess(factoryArgumentArray, Expression.Constant(parameterMap[i]));
+ }
+ else
+ {
+ var parameterTypeExpression = new Expression[] { serviceProvider,
+ Expression.Constant(parameterType, typeof(Type)),
+ Expression.Constant(constructor.DeclaringType, typeof(Type)),
+ Expression.Constant(hasDefaultValue) };
+ constructorArguments[i] = Expression.Call(GetServiceInfo, parameterTypeExpression);
+ }
+
+ // Support optional constructor arguments by passing in the default value
+ // when the argument would otherwise be null.
+ if (hasDefaultValue)
+ {
+ var defaultValueExpression = Expression.Constant(defaultValue);
+ constructorArguments[i] = Expression.Coalesce(constructorArguments[i], defaultValueExpression);
+ }
+
+ constructorArguments[i] = Expression.Convert(constructorArguments[i], parameterType);
+ }
+
+ return Expression.New(constructor, constructorArguments);
+ }
+
+ private static void FindApplicableConstructor(
+ Type instanceType,
+ Type[] argumentTypes,
+ out ConstructorInfo matchingConstructor,
+ out int?[] parameterMap)
+ {
+ matchingConstructor = null;
+ parameterMap = null;
+
+ if (!TryFindPreferredConstructor(instanceType, argumentTypes, ref matchingConstructor, ref parameterMap) &&
+ !TryFindMatchingConstructor(instanceType, argumentTypes, ref matchingConstructor, ref parameterMap))
+ {
+ var message = $"A suitable constructor for type '{instanceType}' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.";
+ throw new InvalidOperationException(message);
+ }
+ }
+
+ // Tries to find constructor based on provided argument types
+ private static bool TryFindMatchingConstructor(
+ Type instanceType,
+ Type[] argumentTypes,
+ ref ConstructorInfo matchingConstructor,
+ ref int?[] parameterMap)
+ {
+ foreach (var constructor in instanceType.GetTypeInfo().DeclaredConstructors)
+ {
+ if (constructor.IsStatic || !constructor.IsPublic)
+ {
+ continue;
+ }
+
+ if (TryCreateParameterMap(constructor.GetParameters(), argumentTypes, out int?[] tempParameterMap))
+ {
+ if (matchingConstructor != null)
+ {
+ throw new InvalidOperationException($"Multiple constructors accepting all given argument types have been found in type '{instanceType}'. There should only be one applicable constructor.");
+ }
+
+ matchingConstructor = constructor;
+ parameterMap = tempParameterMap;
+ }
+ }
+
+ return matchingConstructor != null;
+ }
+
+ // Tries to find constructor marked with ActivatorUtilitiesConstructorAttribute
+ private static bool TryFindPreferredConstructor(
+ Type instanceType,
+ Type[] argumentTypes,
+ ref ConstructorInfo matchingConstructor,
+ ref int?[] parameterMap)
+ {
+ var seenPreferred = false;
+ foreach (var constructor in instanceType.GetTypeInfo().DeclaredConstructors)
+ {
+ if (constructor.IsStatic || !constructor.IsPublic)
+ {
+ continue;
+ }
+
+ if (constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), false))
+ {
+ if (seenPreferred)
+ {
+ ThrowMultipleCtorsMarkedWithAttributeException();
+ }
+
+ if (!TryCreateParameterMap(constructor.GetParameters(), argumentTypes, out int?[] tempParameterMap))
+ {
+ ThrowMarkedCtorDoesNotTakeAllProvidedArguments();
+ }
+
+ matchingConstructor = constructor;
+ parameterMap = tempParameterMap;
+ seenPreferred = true;
+ }
+ }
+
+ return matchingConstructor != null;
+ }
+
+ // Creates an injective parameterMap from givenParameterTypes to assignable constructorParameters.
+ // Returns true if each given parameter type is assignable to a unique; otherwise, false.
+ private static bool TryCreateParameterMap(ParameterInfo[] constructorParameters, Type[] argumentTypes, out int?[] parameterMap)
+ {
+ parameterMap = new int?[constructorParameters.Length];
+
+ for (var i = 0; i < argumentTypes.Length; i++)
+ {
+ var foundMatch = false;
+ var givenParameter = argumentTypes[i].GetTypeInfo();
+
+ for (var j = 0; j < constructorParameters.Length; j++)
+ {
+ if (parameterMap[j] != null)
+ {
+ // This ctor parameter has already been matched
+ continue;
+ }
+
+ if (constructorParameters[j].ParameterType.GetTypeInfo().IsAssignableFrom(givenParameter))
+ {
+ foundMatch = true;
+ parameterMap[j] = i;
+ break;
+ }
+ }
+
+ if (!foundMatch)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private class ConstructorMatcher
+ {
+ private readonly ConstructorInfo _constructor;
+ private readonly ParameterInfo[] _parameters;
+ private readonly object[] _parameterValues;
+ private readonly bool[] _parameterValuesSet;
+
+ public ConstructorMatcher(ConstructorInfo constructor)
+ {
+ _constructor = constructor;
+ _parameters = _constructor.GetParameters();
+ _parameterValuesSet = new bool[_parameters.Length];
+ _parameterValues = new object[_parameters.Length];
+ }
+
+ public int Match(object[] givenParameters)
+ {
+ var applyIndexStart = 0;
+ var applyExactLength = 0;
+ for (var givenIndex = 0; givenIndex != givenParameters.Length; givenIndex++)
+ {
+ var givenType = givenParameters[givenIndex]?.GetType().GetTypeInfo();
+ var givenMatched = false;
+
+ for (var applyIndex = applyIndexStart; givenMatched == false && applyIndex != _parameters.Length; ++applyIndex)
+ {
+ if (_parameterValuesSet[applyIndex] == false &&
+ _parameters[applyIndex].ParameterType.GetTypeInfo().IsAssignableFrom(givenType))
+ {
+ givenMatched = true;
+ _parameterValuesSet[applyIndex] = true;
+ _parameterValues[applyIndex] = givenParameters[givenIndex];
+ if (applyIndexStart == applyIndex)
+ {
+ applyIndexStart++;
+ if (applyIndex == givenIndex)
+ {
+ applyExactLength = applyIndex;
+ }
+ }
+ }
+ }
+
+ if (givenMatched == false)
+ {
+ return -1;
+ }
+ }
+ return applyExactLength;
+ }
+
+ public object CreateInstance(IServiceProvider provider)
+ {
+ for (var index = 0; index != _parameters.Length; index++)
+ {
+ if (_parameterValuesSet[index] == false)
+ {
+ var value = provider.GetService(_parameters[index].ParameterType);
+ if (value == null)
+ {
+ if (!ParameterDefaultValue.TryGetDefaultValue(_parameters[index], out var defaultValue))
+ {
+ throw new InvalidOperationException($"Unable to resolve service for type '{_parameters[index].ParameterType}' while attempting to activate '{_constructor.DeclaringType}'.");
+ }
+ else
+ {
+ _parameterValues[index] = defaultValue;
+ }
+ }
+ else
+ {
+ _parameterValues[index] = value;
+ }
+ }
+ }
+
+ try
+ {
+ return _constructor.Invoke(_parameterValues);
+ }
+ catch (TargetInvocationException ex)
+ {
+ ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
+ // The above line will always throw, but the compiler requires we throw explicitly.
+ throw;
+ }
+ }
+ }
+
+ private static void ThrowMultipleCtorsMarkedWithAttributeException()
+ {
+ throw new InvalidOperationException($"Multiple constructors were marked with {nameof(ActivatorUtilitiesConstructorAttribute)}.");
+ }
+
+ private static void ThrowMarkedCtorDoesNotTakeAllProvidedArguments()
+ {
+ throw new InvalidOperationException($"Constructor marked with {nameof(ActivatorUtilitiesConstructorAttribute)} does not accept all given argument types.");
+ }
+ }
+}
diff --git a/src/Shared/ActivatorUtilities/ActivatorUtilitiesConstructorAttribute.cs b/src/Shared/ActivatorUtilities/ActivatorUtilitiesConstructorAttribute.cs
new file mode 100644
index 0000000000..67ffa13f6f
--- /dev/null
+++ b/src/Shared/ActivatorUtilities/ActivatorUtilitiesConstructorAttribute.cs
@@ -0,0 +1,26 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+#if ActivatorUtilities_In_DependencyInjection
+namespace Microsoft.Extensions.DependencyInjection
+#else
+namespace Microsoft.Extensions.Internal
+#endif
+{
+ ///
+ /// Marks the constructor to be used when activating type using .
+ ///
+
+#if ActivatorUtilities_In_DependencyInjection
+ public
+#else
+ // Do not take a dependency on this class unless you are explicitly trying to avoid taking a
+ // dependency on Microsoft.AspNetCore.DependencyInjection.Abstractions.
+ internal
+#endif
+ class ActivatorUtilitiesConstructorAttribute: Attribute
+ {
+ }
+}
diff --git a/src/Shared/ActivatorUtilities/ObjectFactory.cs b/src/Shared/ActivatorUtilities/ObjectFactory.cs
new file mode 100644
index 0000000000..517247811e
--- /dev/null
+++ b/src/Shared/ActivatorUtilities/ObjectFactory.cs
@@ -0,0 +1,25 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+#if ActivatorUtilities_In_DependencyInjection
+namespace Microsoft.Extensions.DependencyInjection
+#else
+namespace Microsoft.Extensions.Internal
+#endif
+{
+
+ ///
+ /// The result of .
+ ///
+ /// The to get service arguments from.
+ /// Additional constructor arguments.
+ /// The instantiated type.
+#if ActivatorUtilities_In_DependencyInjection
+ public
+#else
+ internal
+#endif
+ delegate object ObjectFactory(IServiceProvider serviceProvider, object[] arguments);
+}
\ No newline at end of file
diff --git a/src/Shared/ActivatorUtilities/sharedsources.props b/src/Shared/ActivatorUtilities/sharedsources.props
new file mode 100644
index 0000000000..b35fe34b10
--- /dev/null
+++ b/src/Shared/ActivatorUtilities/sharedsources.props
@@ -0,0 +1,8 @@
+
+
+
+ true
+ $(ContentTargetFolders)\cs\netstandard1.0\
+
+
+
diff --git a/src/Shared/ParameterDefaultValue/ParameterDefaultValue.cs b/src/Shared/ParameterDefaultValue/ParameterDefaultValue.cs
new file mode 100644
index 0000000000..a71bad37b1
--- /dev/null
+++ b/src/Shared/ParameterDefaultValue/ParameterDefaultValue.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Reflection;
+
+namespace Microsoft.Extensions.Internal
+{
+ internal class ParameterDefaultValue
+ {
+ public static bool TryGetDefaultValue(ParameterInfo parameter, out object defaultValue)
+ {
+ bool hasDefaultValue;
+ var tryToGetDefaultValue = true;
+ defaultValue = null;
+
+ try
+ {
+ hasDefaultValue = parameter.HasDefaultValue;
+ }
+ catch (FormatException) when (parameter.ParameterType == typeof(DateTime))
+ {
+ // Workaround for https://github.com/dotnet/corefx/issues/12338
+ // If HasDefaultValue throws FormatException for DateTime
+ // we expect it to have default value
+ hasDefaultValue = true;
+ tryToGetDefaultValue = false;
+ }
+
+ if (hasDefaultValue)
+ {
+ if (tryToGetDefaultValue)
+ {
+ defaultValue = parameter.DefaultValue;
+ }
+
+ // Workaround for https://github.com/dotnet/corefx/issues/11797
+ if (defaultValue == null && parameter.ParameterType.IsValueType)
+ {
+ defaultValue = Activator.CreateInstance(parameter.ParameterType);
+ }
+ }
+
+ return hasDefaultValue;
+ }
+ }
+}