Fix for #1416 - Remove all uses of ITypeActivator and use the static method instead

- ITypeActivator is being removed
- Where an ITypeActivator was used before, use the static ActivatorUtilities
This commit is contained in:
Stephen Halter 2014-12-17 15:38:17 -08:00 committed by Kirthi Krishnamraju
parent 94ef6cf8fa
commit 5de210f527
38 changed files with 279 additions and 249 deletions

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
@ -12,17 +11,21 @@ namespace Microsoft.AspNet.Mvc
/// </summary> /// </summary>
public class DefaultControllerActivator : IControllerActivator public class DefaultControllerActivator : IControllerActivator
{ {
private static readonly Func<Type, ObjectFactory> _createControllerFactory = private readonly ITypeActivatorCache _typeActivatorCache;
type => ActivatorUtilities.CreateFactory(type, Type.EmptyTypes);
private readonly ConcurrentDictionary<Type, ObjectFactory> _controllerFactories =
new ConcurrentDictionary<Type, ObjectFactory>();
/// <summary>
/// Creates a new <see cref="DefaultControllerActivator"/>.
/// </summary>
/// <param name="typeActivatorCache">The <see cref="ITypeActivatorCache"/>.</param>
public DefaultControllerActivator(ITypeActivatorCache typeActivatorCache)
{
_typeActivatorCache = typeActivatorCache;
}
/// <inheritdoc /> /// <inheritdoc />
public object Create([NotNull] ActionContext actionContext, [NotNull] Type controllerType) public object Create([NotNull] ActionContext actionContext, [NotNull] Type controllerType)
{ {
var factory = _controllerFactories.GetOrAdd(controllerType, _createControllerFactory); var serviceProvider = actionContext.HttpContext.RequestServices;
return factory(actionContext.HttpContext.RequestServices, arguments: null); return _typeActivatorCache.CreateInstance<object>(serviceProvider, controllerType);
} }
} }
} }

View File

@ -0,0 +1,30 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Concurrent;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Caches <see cref="ObjectFactory"/> instances produced by
/// <see cref="ActivatorUtilities.CreateFactory(Type, Type[])"/>.
/// </summary>
public class DefaultTypeActivatorCache : ITypeActivatorCache
{
private readonly Func<Type, ObjectFactory> _createFactory =
(type) => ActivatorUtilities.CreateFactory(type, Type.EmptyTypes);
private readonly ConcurrentDictionary<Type, ObjectFactory> _typeActivatorCache =
new ConcurrentDictionary<Type, ObjectFactory>();
/// <inheritdoc/>
public TInstance CreateInstance<TInstance>(
[NotNull] IServiceProvider serviceProvider,
[NotNull] Type implementationType)
{
var createFactory = _typeActivatorCache.GetOrAdd(implementationType, _createFactory);
return (TInstance)createFactory(serviceProvider, arguments: null);
}
}
}

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -14,16 +13,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
: OptionDescriptorBasedProvider<IExcludeTypeValidationFilter>, IValidationExcludeFiltersProvider : OptionDescriptorBasedProvider<IExcludeTypeValidationFilter>, IValidationExcludeFiltersProvider
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the DefaultBodyValidationExcludeFiltersProvider class. /// Initializes a new instance of the <see cref="DefaultValidationExcludeFiltersProvider"/> class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">The <see cref="ITypeActivatorCache"/> cache.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">The <see cref="IServiceProvider"/>.</param>
/// service collection.</param>
public DefaultValidationExcludeFiltersProvider(IOptions<MvcOptions> optionsAccessor, public DefaultValidationExcludeFiltersProvider(IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ValidationExcludeFilters, typeActivator, serviceProvider) : base(optionsAccessor.Options.ValidationExcludeFilters, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -19,7 +19,8 @@ namespace Microsoft.AspNet.Mvc
/// <param name="filterType">Type representing an <see cref="IFilter"/>.</param> /// <param name="filterType">Type representing an <see cref="IFilter"/>.</param>
/// <returns>An <see cref="IFilter"/> representing the added type.</returns> /// <returns>An <see cref="IFilter"/> representing the added type.</returns>
/// <remarks> /// <remarks>
/// Filter instances will be created using <see cref="Microsoft.Framework.DependencyInjection.ITypeActivator"/>. /// Filter instances will be created using
/// <see cref="Microsoft.Framework.DependencyInjection.ActivatorUtilities"/>.
/// Use <see cref="AddService(ICollection{IFilter}, Type)"/> to register a service as a filter. /// Use <see cref="AddService(ICollection{IFilter}, Type)"/> to register a service as a filter.
/// </remarks> /// </remarks>
public static IFilter Add( public static IFilter Add(
@ -37,7 +38,8 @@ namespace Microsoft.AspNet.Mvc
/// <param name="order">The order of the added filter.</param> /// <param name="order">The order of the added filter.</param>
/// <returns>An <see cref="IFilter"/> representing the added type.</returns> /// <returns>An <see cref="IFilter"/> representing the added type.</returns>
/// <remarks> /// <remarks>
/// Filter instances will be created using <see cref="Microsoft.Framework.DependencyInjection.ITypeActivator"/>. /// Filter instances will be created using
/// <see cref="Microsoft.Framework.DependencyInjection.ActivatorUtilities"/>.
/// Use <see cref="AddService(ICollection{IFilter}, Type)"/> to register a service as a filter. /// Use <see cref="AddService(ICollection{IFilter}, Type)"/> to register a service as a filter.
/// </remarks> /// </remarks>
public static IFilter Add( public static IFilter Add(

View File

@ -3,7 +3,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.AspNet.Mvc.Core; using System.Linq;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
@ -12,6 +12,8 @@ namespace Microsoft.AspNet.Mvc
[DebuggerDisplay("TypeFilter: Type={ImplementationType} Order={Order}")] [DebuggerDisplay("TypeFilter: Type={ImplementationType} Order={Order}")]
public class TypeFilterAttribute : Attribute, IFilterFactory, IOrderedFilter public class TypeFilterAttribute : Attribute, IFilterFactory, IOrderedFilter
{ {
private ObjectFactory _factory;
public TypeFilterAttribute([NotNull] Type type) public TypeFilterAttribute([NotNull] Type type)
{ {
ImplementationType = type; ImplementationType = type;
@ -25,18 +27,14 @@ namespace Microsoft.AspNet.Mvc
public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider) public IFilter CreateInstance([NotNull] IServiceProvider serviceProvider)
{ {
var activator = serviceProvider.GetRequiredService<ITypeActivator>(); if (_factory == null)
var obj = activator.CreateInstance(serviceProvider, ImplementationType, Arguments ?? new object[0]);
var filter = obj as IFilter;
if (filter == null)
{ {
throw new InvalidOperationException(Resources.FormatFilterFactoryAttribute_TypeMustImplementIFilter( var argumentTypes = Arguments?.Select(a => a.GetType())?.ToArray();
typeof(TypeFilterAttribute).Name,
typeof(IFilter).Name)); _factory = ActivatorUtilities.CreateFactory(ImplementationType, argumentTypes ?? Type.EmptyTypes);
} }
return filter; return (IFilter)_factory(serviceProvider, Arguments);
} }
} }
} }

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -16,13 +15,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the DefaultInputFormattersProvider class. /// Initializes a new instance of the DefaultInputFormattersProvider class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates an instance
/// of type <see cref="IInputFormatter"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultInputFormattersProvider(IOptions<MvcOptions> optionsAccessor, public DefaultInputFormattersProvider(IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.InputFormatters, typeActivator, serviceProvider) : base(optionsAccessor.Options.InputFormatters, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.OptionDescriptors; using Microsoft.AspNet.Mvc.OptionDescriptors;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
@ -17,13 +16,14 @@ namespace Microsoft.AspNet.Mvc
/// Initializes a new instance of the DefaultOutputFormattersProvider class. /// Initializes a new instance of the DefaultOutputFormattersProvider class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates an instance
/// of type <see cref="IOutputFormatter"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultOutputFormattersProvider(IOptions<MvcOptions> optionsAccessor, public DefaultOutputFormattersProvider(IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.OutputFormatters, typeActivator, serviceProvider) : base(optionsAccessor.Options.OutputFormatters, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Caches <see cref="Microsoft.Framework.DependencyInjection.ObjectFactory"/> instances produced by
/// <see cref="Microsoft.Framework.DependencyInjection.ActivatorUtilities.CreateFactory(Type, Type[])"/>.
/// </summary>
public interface ITypeActivatorCache
{
/// <summary>
/// Creates an instance of <typeparamref name="TInstance"/>.
/// </summary>
/// <param name="serviceProvider">The <see cref="IServiceProvider"/> used to resolve dependencies for
/// <paramref name="implementationType"/>.</param>
/// <param name="implementationType">The <see cref="Type"/> of the <typeparamref name="TInstance"/> to create.</param>
TInstance CreateInstance<TInstance>(IServiceProvider serviceProvider, Type optionType);
}
}

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -16,14 +15,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the DefaultModelBindersProvider class. /// Initializes a new instance of the DefaultModelBindersProvider class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates an instance
/// of type <see cref="IModelBinder"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultModelBindersProvider( public DefaultModelBindersProvider(
IOptions<MvcOptions> optionsAccessor, IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ModelBinders, typeActivator, serviceProvider) : base(optionsAccessor.Options.ModelBinders, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -17,14 +16,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultModelValidatorProviderProvider"/> class. /// Initializes a new instance of the <see cref="DefaultModelValidatorProviderProvider"/> class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates an instance
/// of type <see cref="IModelValidatorProvider"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultModelValidatorProviderProvider( public DefaultModelValidatorProviderProvider(
IOptions<MvcOptions> optionsAccessor, IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ModelValidatorProviders, typeActivator, serviceProvider) : base(optionsAccessor.Options.ModelValidatorProviders, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -17,14 +16,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultValueProviderFactoryProvider"/> class. /// Initializes a new instance of the <see cref="DefaultValueProviderFactoryProvider"/> class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name = "typeActivatorCache" > As <see cref="ITypeActivatorCache"/> instance that creates
/// an instance of type <see cref="IValueProviderFactory"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultValueProviderFactoryProvider( public DefaultValueProviderFactoryProvider(
IOptions<MvcOptions> optionsAccessor, IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ValueProviderFactories, typeActivator, serviceProvider) : base(optionsAccessor.Options.ValueProviderFactories, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -16,14 +15,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultViewEngineProvider"/> class. /// Initializes a new instance of the <see cref="DefaultViewEngineProvider"/> class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates
/// an instance of type <see cref="IViewEngine"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultViewEngineProvider( public DefaultViewEngineProvider(
IOptions<MvcOptions> optionsAccessor, IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ViewEngines, typeActivator, serviceProvider) : base(optionsAccessor.Options.ViewEngines, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -15,16 +15,24 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
public abstract class OptionDescriptorBasedProvider<TOption> public abstract class OptionDescriptorBasedProvider<TOption>
{ {
private readonly IEnumerable<OptionDescriptor<TOption>> _optionDescriptors; private readonly IEnumerable<OptionDescriptor<TOption>> _optionDescriptors;
private readonly ITypeActivator _typeActivator; private ITypeActivatorCache _typeActivatorCache;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
/// <summary>
/// Initializes a new instance of the <see cref="OptionDescriptorBasedProvider{TOption}"/> class.
/// </summary>
/// <param name="optionDescriptors">An enumerable of <see cref="OptionDescriptor{TOption}"/>.</param>
/// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates an
/// instance of type <typeparamref name="TOption"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param>
public OptionDescriptorBasedProvider( public OptionDescriptorBasedProvider(
[NotNull] IEnumerable<OptionDescriptor<TOption>> optionDescriptors, [NotNull] IEnumerable<OptionDescriptor<TOption>> optionDescriptors,
[NotNull] ITypeActivator typeActivator, [NotNull] ITypeActivatorCache typeActivatorCache,
[NotNull] IServiceProvider serviceProvider) [NotNull] IServiceProvider serviceProvider)
{ {
_optionDescriptors = optionDescriptors; _optionDescriptors = optionDescriptors;
_typeActivator = typeActivator; _typeActivatorCache = typeActivatorCache;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
@ -41,8 +49,7 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var instance = descriptor.Instance; var instance = descriptor.Instance;
if (instance == null) if (instance == null)
{ {
instance = (TOption)_typeActivator.CreateInstance(_serviceProvider, instance = _typeActivatorCache.CreateInstance<TOption>(_serviceProvider, descriptor.OptionType);
descriptor.OptionType);
} }
result.Add(instance); result.Add(instance);

View File

@ -14,20 +14,20 @@ namespace Microsoft.AspNet.Mvc
public class DefaultViewComponentInvoker : IViewComponentInvoker public class DefaultViewComponentInvoker : IViewComponentInvoker
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ITypeActivator _activator; private readonly ITypeActivatorCache _typeActivatorCache;
private readonly TypeInfo _componentType; private readonly TypeInfo _componentType;
private readonly IViewComponentActivator _viewComponentActivator; private readonly IViewComponentActivator _viewComponentActivator;
private readonly object[] _args; private readonly object[] _args;
public DefaultViewComponentInvoker( public DefaultViewComponentInvoker(
[NotNull] IServiceProvider serviceProvider, [NotNull] IServiceProvider serviceProvider,
[NotNull] ITypeActivator activator, [NotNull] ITypeActivatorCache typeActivatorCache,
[NotNull] IViewComponentActivator viewComponentActivator, [NotNull] IViewComponentActivator viewComponentActivator,
[NotNull] TypeInfo componentType, [NotNull] TypeInfo componentType,
object[] args) object[] args)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_activator = activator; _typeActivatorCache = typeActivatorCache;
_componentType = componentType; _componentType = componentType;
_viewComponentActivator = viewComponentActivator; _viewComponentActivator = viewComponentActivator;
_args = args ?? new object[0]; _args = args ?? new object[0];
@ -77,7 +77,7 @@ namespace Microsoft.AspNet.Mvc
private object CreateComponent([NotNull] ViewContext context) private object CreateComponent([NotNull] ViewContext context)
{ {
var component = _activator.CreateInstance(_serviceProvider, _componentType.AsType()); var component = _typeActivatorCache.CreateInstance<object>(_serviceProvider, _componentType.AsType());
_viewComponentActivator.Activate(component, context); _viewComponentActivator.Activate(component, context);
return component; return component;
} }

View File

@ -9,16 +9,16 @@ namespace Microsoft.AspNet.Mvc
public class DefaultViewComponentInvokerProvider : IViewComponentInvokerProvider public class DefaultViewComponentInvokerProvider : IViewComponentInvokerProvider
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ITypeActivator _typeActivator; private readonly ITypeActivatorCache _typeActivatorCache;
private readonly IViewComponentActivator _viewComponentActivator; private readonly IViewComponentActivator _viewComponentActivator;
public DefaultViewComponentInvokerProvider( public DefaultViewComponentInvokerProvider(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IViewComponentActivator viewComponentActivator) IViewComponentActivator viewComponentActivator)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_typeActivator = typeActivator; _typeActivatorCache = typeActivatorCache;
_viewComponentActivator = viewComponentActivator; _viewComponentActivator = viewComponentActivator;
} }
@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc
{ {
context.Result = new DefaultViewComponentInvoker( context.Result = new DefaultViewComponentInvoker(
_serviceProvider, _serviceProvider,
_typeActivator, _typeActivatorCache,
_viewComponentActivator, _viewComponentActivator,
context.ComponentType, context.ComponentType,
context.Arguments); context.Arguments);

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Mvc
/// For use when creating a <see cref="ViewDataDictionary{TModel}"/> for a new top-level scope. /// For use when creating a <see cref="ViewDataDictionary{TModel}"/> for a new top-level scope.
/// </remarks> /// </remarks>
/// <inheritdoc /> /// <inheritdoc />
// References may not show up due to ITypeActivator use in RazorPageActivator. // References may not show up due to ActivatorUtilities use in RazorPageActivator.
public ViewDataDictionary( public ViewDataDictionary(
[NotNull] IModelMetadataProvider metadataProvider, [NotNull] IModelMetadataProvider metadataProvider,
[NotNull] ModelStateDictionary modelState) [NotNull] ModelStateDictionary modelState)
@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Mvc
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <inheritdoc /> /// <inheritdoc />
// References may not show up due to ITypeActivator use in RazorPageActivator. // References may not show up due to ActivatorUtilities use in RazorPageActivator.
public ViewDataDictionary([NotNull] ViewDataDictionary source) public ViewDataDictionary([NotNull] ViewDataDictionary source)
: base(source, declaredModelType: typeof(TModel)) : base(source, declaredModelType: typeof(TModel))
{ {

View File

@ -17,6 +17,8 @@ namespace Microsoft.AspNet.Mvc
private static readonly Func<ModelBindingContext, string, bool> _defaultFilter = private static readonly Func<ModelBindingContext, string, bool> _defaultFilter =
(context, propertyName) => true; (context, propertyName) => true;
private ObjectFactory _factory;
private Func<ModelBindingContext, string, bool> _predicateFromInclude; private Func<ModelBindingContext, string, bool> _predicateFromInclude;
/// <summary> /// <summary>
@ -79,7 +81,8 @@ namespace Microsoft.AspNet.Mvc
{ {
if (PredicateProviderType != null) if (PredicateProviderType != null)
{ {
return CreatePredicateFromProviderType(PredicateProviderType); var factory = GetFactory();
return CreatePredicateFromProviderType(factory);
} }
else if (Include != null && Include.Length > 0) else if (Include != null && Include.Length > 0)
{ {
@ -98,8 +101,17 @@ namespace Microsoft.AspNet.Mvc
} }
} }
private ObjectFactory GetFactory()
{
if (_factory == null)
{
_factory = ActivatorUtilities.CreateFactory(PredicateProviderType, Type.EmptyTypes);
}
return _factory;
}
private static Func<ModelBindingContext, string, bool> CreatePredicateFromProviderType( private static Func<ModelBindingContext, string, bool> CreatePredicateFromProviderType(
Type predicateProviderType) ObjectFactory factory)
{ {
// Holding state to avoid execessive creation of the provider. // Holding state to avoid execessive creation of the provider.
var initialized = false; var initialized = false;
@ -110,11 +122,8 @@ namespace Microsoft.AspNet.Mvc
if (!initialized) if (!initialized)
{ {
var services = context.OperationBindingContext.HttpContext.RequestServices; var services = context.OperationBindingContext.HttpContext.RequestServices;
var activator = services.GetService<ITypeActivator>();
var provider = (IPropertyBindingPredicateProvider)activator.CreateInstance( var provider = (IPropertyBindingPredicateProvider)factory(services, arguments: null);
services,
predicateProviderType);
initialized = true; initialized = true;
predicate = provider.PropertyFilter ?? _defaultFilter; predicate = provider.PropertyFilter ?? _defaultFilter;

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
@ -14,16 +15,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
/// </summary> /// </summary>
public class BinderTypeBasedModelBinder : IModelBinder public class BinderTypeBasedModelBinder : IModelBinder
{ {
private readonly ITypeActivator _typeActivator; private readonly Func<Type, ObjectFactory> _createFactory =
(t) => ActivatorUtilities.CreateFactory(t, Type.EmptyTypes);
private ConcurrentDictionary<Type, ObjectFactory> _typeActivatorCache =
new ConcurrentDictionary<Type, ObjectFactory>();
/// <summary>
/// Creates a new instance of <see cref="BinderTypeBasedModelBinder"/>.
/// </summary>
/// <param name="typeActivator">The <see cref="ITypeActivator"/>.</param>
public BinderTypeBasedModelBinder([NotNull] ITypeActivator typeActivator)
{
_typeActivator = typeActivator;
}
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext) public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
{ {
@ -35,7 +31,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
} }
var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices; var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
var instance = _typeActivator.CreateInstance(requestServices, bindingContext.ModelMetadata.BinderType); var createFactory = _typeActivatorCache.GetOrAdd(bindingContext.ModelMetadata.BinderType, _createFactory);
var instance = createFactory(requestServices, arguments: null);
var modelBinder = instance as IModelBinder; var modelBinder = instance as IModelBinder;
if (modelBinder == null) if (modelBinder == null)

View File

@ -7,27 +7,17 @@ using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding.Internal; using Microsoft.AspNet.Mvc.ModelBinding.Internal;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.ModelBinding namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
public class GenericModelBinder : IModelBinder public class GenericModelBinder : IModelBinder
{ {
private readonly ITypeActivator _activator;
private readonly IServiceProvider _serviceProvider;
public GenericModelBinder(IServiceProvider serviceProvider, ITypeActivator activator)
{
_serviceProvider = serviceProvider;
_activator = activator;
}
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext) public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
{ {
var binderType = ResolveBinderType(bindingContext.ModelType); var binderType = ResolveBinderType(bindingContext.ModelType);
if (binderType != null) if (binderType != null)
{ {
var binder = (IModelBinder)_activator.CreateInstance(_serviceProvider, binderType); var binder = (IModelBinder)Activator.CreateInstance(binderType);
await binder.BindModelAsync(bindingContext); await binder.BindModelAsync(bindingContext);
// Was able to resolve a binder type, hence we should tell the model binding system to return // Was able to resolve a binder type, hence we should tell the model binding system to return

View File

@ -17,14 +17,15 @@ namespace Microsoft.AspNet.Mvc.Razor.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultViewLocationExpanderProvider"/> class. /// Initializes a new instance of the <see cref="DefaultViewLocationExpanderProvider"/> class.
/// </summary> /// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param> /// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param> /// <param name="typeActivatorCache">A <see cref="ITypeActivatorCache"/> instance that creates a new instance
/// of type <see cref="IViewLocationExpander"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the /// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param> /// service collection.</param>
public DefaultViewLocationExpanderProvider( public DefaultViewLocationExpanderProvider(
IOptions<RazorViewEngineOptions> optionsAccessor, IOptions<RazorViewEngineOptions> optionsAccessor,
ITypeActivator typeActivator, ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ViewLocationExpanders, typeActivator, serviceProvider) : base(optionsAccessor.Options.ViewLocationExpanders, typeActivatorCache, serviceProvider)
{ {
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Reflection; using System.Reflection;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
@ -14,16 +15,16 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
// Name of the "public TModel Model" property on RazorPage<TModel> // Name of the "public TModel Model" property on RazorPage<TModel>
private const string ModelPropertyName = "Model"; private const string ModelPropertyName = "Model";
private readonly ITypeActivator _typeActivator;
private readonly ConcurrentDictionary<Type, PageActivationInfo> _activationInfo; private readonly ConcurrentDictionary<Type, PageActivationInfo> _activationInfo;
private readonly IModelMetadataProvider _metadataProvider;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RazorPageActivator"/> class. /// Initializes a new instance of the <see cref="RazorPageActivator"/> class.
/// </summary> /// </summary>
public RazorPageActivator(ITypeActivator typeActivator) public RazorPageActivator(IModelMetadataProvider metadataProvider)
{ {
_typeActivator = typeActivator;
_activationInfo = new ConcurrentDictionary<Type, PageActivationInfo>(); _activationInfo = new ConcurrentDictionary<Type, PageActivationInfo>();
_metadataProvider = metadataProvider;
} }
/// <inheritdoc /> /// <inheritdoc />
@ -48,16 +49,15 @@ namespace Microsoft.AspNet.Mvc.Razor
if (context.ViewData == null) if (context.ViewData == null)
{ {
// Create ViewDataDictionary<TModel>(IModelMetadataProvider, ModelStateDictionary). // Create ViewDataDictionary<TModel>(IModelMetadataProvider, ModelStateDictionary).
return (ViewDataDictionary)_typeActivator.CreateInstance(context.HttpContext.RequestServices, return (ViewDataDictionary)Activator.CreateInstance(activationInfo.ViewDataDictionaryType,
activationInfo.ViewDataDictionaryType, _metadataProvider,
context.ModelState); context.ModelState);
} }
else if (context.ViewData.GetType() != activationInfo.ViewDataDictionaryType) else if (context.ViewData.GetType() != activationInfo.ViewDataDictionaryType)
{ {
// Create ViewDataDictionary<TModel>(ViewDataDictionary). // Create ViewDataDictionary<TModel>(ViewDataDictionary).
return (ViewDataDictionary)_typeActivator.CreateInstance(context.HttpContext.RequestServices, return (ViewDataDictionary)Activator.CreateInstance(activationInfo.ViewDataDictionaryType,
activationInfo.ViewDataDictionaryType, context.ViewData);
context.ViewData);
} }
return context.ViewData; return context.ViewData;

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor namespace Microsoft.AspNet.Mvc.Razor
@ -12,16 +13,13 @@ namespace Microsoft.AspNet.Mvc.Razor
/// </summary> /// </summary>
public class VirtualPathRazorPageFactory : IRazorPageFactory public class VirtualPathRazorPageFactory : IRazorPageFactory
{ {
private readonly ITypeActivator _activator;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ICompilerCache _compilerCache; private readonly ICompilerCache _compilerCache;
private IRazorCompilationService _razorcompilationService; private IRazorCompilationService _razorcompilationService;
public VirtualPathRazorPageFactory(ITypeActivator typeActivator, public VirtualPathRazorPageFactory(IServiceProvider serviceProvider,
IServiceProvider serviceProvider,
ICompilerCache compilerCache) ICompilerCache compilerCache)
{ {
_activator = typeActivator;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_compilerCache = compilerCache; _compilerCache = compilerCache;
} }
@ -60,7 +58,7 @@ namespace Microsoft.AspNet.Mvc.Razor
return null; return null;
} }
var page = (IRazorPage)_activator.CreateInstance(_serviceProvider, result.CompilationResult.CompiledType); var page = (IRazorPage)Activator.CreateInstance(result.CompilationResult.CompiledType);
page.Path = relativePath; page.Path = relativePath;
return page; return page;

View File

@ -37,8 +37,8 @@ namespace Microsoft.AspNet.Mvc
typeof(INestedProviderManagerAsync<>), typeof(INestedProviderManagerAsync<>),
typeof(NestedProviderManagerAsync<>)); typeof(NestedProviderManagerAsync<>));
yield return describe.Transient<MvcMarkerService, MvcMarkerService>(); yield return describe.Transient<MvcMarkerService, MvcMarkerService>();
yield return describe.Singleton(typeof(ITypeActivatorCache), typeof(DefaultTypeActivatorCache));
yield return describe.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)); yield return describe.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>));
// Core action discovery, filters and action execution. // Core action discovery, filters and action execution.
// These are consumed only when creating action descriptors, then they can be de-allocated // These are consumed only when creating action descriptors, then they can be de-allocated
@ -49,8 +49,7 @@ namespace Microsoft.AspNet.Mvc
// This has a cache, so it needs to be a singleton // This has a cache, so it needs to be a singleton
yield return describe.Singleton<IControllerFactory, DefaultControllerFactory>(); yield return describe.Singleton<IControllerFactory, DefaultControllerFactory>();
// This has a cache, so it needs to be a singleton yield return describe.Transient<IControllerActivator, DefaultControllerActivator>();
yield return describe.Singleton<IControllerActivator, DefaultControllerActivator>();
// This accesses per-reqest services // This accesses per-reqest services
yield return describe.Transient<IActionInvokerFactory, ActionInvokerFactory>(); yield return describe.Transient<IActionInvokerFactory, ActionInvokerFactory>();
@ -78,9 +77,7 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Transient<INestedProvider<FilterProviderContext>, DefaultFilterProvider>(); yield return describe.Transient<INestedProvider<FilterProviderContext>, DefaultFilterProvider>();
yield return describe.Transient<FormatFilter, FormatFilter>(); yield return describe.Transient<FormatFilter, FormatFilter>();
// Dataflow - ModelBinding, Validation and Formatting // Dataflow - ModelBinding, Validation and Formatting
// The DataAnnotationsModelMetadataProvider does significant caching of reflection/attributes // The DataAnnotationsModelMetadataProvider does significant caching of reflection/attributes
// and thus needs to be singleton. // and thus needs to be singleton.
yield return describe.Singleton<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>(); yield return describe.Singleton<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>();

View File

@ -17,8 +17,14 @@ namespace Microsoft.AspNet.Mvc
public void Create_CreatesInstancesOfTypes(Type type) public void Create_CreatesInstancesOfTypes(Type type)
{ {
// Arrange // Arrange
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator(new DefaultTypeActivatorCache());
var actionContext = new ActionContext(new DefaultHttpContext(), var serviceProvider = new Mock<IServiceProvider>(MockBehavior.Strict);
var httpContext = new DefaultHttpContext
{
RequestServices = serviceProvider.Object
};
var actionContext = new ActionContext(httpContext,
new RouteData(), new RouteData(),
new ActionDescriptor()); new ActionDescriptor());
// Act // Act
@ -32,12 +38,13 @@ namespace Microsoft.AspNet.Mvc
public void Create_TypeActivatesTypesWithServices() public void Create_TypeActivatesTypesWithServices()
{ {
// Arrange // Arrange
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator(new DefaultTypeActivatorCache());
var serviceProvider = new Mock<IServiceProvider>(MockBehavior.Strict); var serviceProvider = new Mock<IServiceProvider>(MockBehavior.Strict);
var testService = new TestService(); var testService = new TestService();
serviceProvider.Setup(s => s.GetService(typeof(TestService))) serviceProvider.Setup(s => s.GetService(typeof(TestService)))
.Returns(testService) .Returns(testService)
.Verifiable(); .Verifiable();
var httpContext = new DefaultHttpContext var httpContext = new DefaultHttpContext
{ {
RequestServices = serviceProvider.Object RequestServices = serviceProvider.Object

View File

@ -79,7 +79,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act // Act
var result = factory.CreateController(context); var result = factory.CreateController(context);
@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act // Act
var result = factory.CreateController(context); var result = factory.CreateController(context);
@ -132,7 +132,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act // Act
var result = factory.CreateController(context); var result = factory.CreateController(context);
@ -158,7 +158,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act // Act
var result = factory.CreateController(context); var result = factory.CreateController(context);
@ -184,7 +184,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act // Act
var result = factory.CreateController(context); var result = factory.CreateController(context);
@ -208,7 +208,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act // Act
var result = factory.CreateController(context); var result = factory.CreateController(context);
@ -232,7 +232,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services RequestServices = services
}; };
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor); var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator()); var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act and Assert // Act and Assert
var exception = Assert.Throws<InvalidOperationException>(() => factory.CreateController(context)); var exception = Assert.Throws<InvalidOperationException>(() => factory.CreateController(context));

View File

@ -25,12 +25,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>(); var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options) optionsAccessor.SetupGet(o => o.Options)
.Returns(options); .Returns(options);
var activator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService))) serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service); .Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var provider = new DefaultModelBindersProvider(optionsAccessor.Object, activator, serviceProvider.Object); var provider = new DefaultModelBindersProvider(optionsAccessor.Object,
typeActivatorCache,
serviceProvider.Object);
// Act // Act
var binders = provider.ModelBinders; var binders = provider.ModelBinders;

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using Microsoft.Framework.DependencyInjection; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Moq; using Moq;
using Xunit; using Xunit;
@ -22,11 +22,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>(); var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options) optionsAccessor.SetupGet(o => o.Options)
.Returns(options); .Returns(options);
var activator = new TypeActivator(); var typeActivatorCache = new Mock<ITypeActivatorCache>();
var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object, var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator, typeActivatorCache.Object,
serviceProvider.Object); serviceProvider.Object);
// Act // Act
var filters = provider.ExcludeFilters; var filters = provider.ExcludeFilters;
@ -47,11 +50,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>(); var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options) optionsAccessor.SetupGet(o => o.Options)
.Returns(options); .Returns(options);
var activator = new TypeActivator(); var typeActivatorCache = new Mock<ITypeActivatorCache>();
var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object, var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator, typeActivatorCache.Object,
serviceProvider.Object); serviceProvider.Object);
// Act // Act
var filters = provider.ExcludeFilters; var filters = provider.ExcludeFilters;
@ -72,11 +78,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>(); var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options) optionsAccessor.SetupGet(o => o.Options)
.Returns(options); .Returns(options);
var activator = new TypeActivator(); var typeActivatorCache = new Mock<ITypeActivatorCache>();
var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object, var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator, typeActivatorCache.Object,
serviceProvider.Object); serviceProvider.Object);
// Act // Act
var filters = provider.ExcludeFilters; var filters = provider.ExcludeFilters;
@ -98,11 +107,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>(); var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options) optionsAccessor.SetupGet(o => o.Options)
.Returns(options); .Returns(options);
var activator = new TypeActivator(); var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var typeActivatorCache = new Mock<ITypeActivatorCache>();
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object, var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator, typeActivatorCache.Object,
serviceProvider.Object); serviceProvider.Object);
// Act // Act
var filters = provider.ExcludeFilters; var filters = provider.ExcludeFilters;
@ -131,6 +143,10 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
{ {
} }
} }
public interface ITestService
{
}
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Moq; using Moq;
using Xunit; using Xunit;
@ -20,10 +19,10 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var service = Mock.Of<ITestService>(); var service = Mock.Of<ITestService>();
var validationProvider = Mock.Of<IModelValidatorProvider>(); var validationProvider = Mock.Of<IModelValidatorProvider>();
var type = typeof(TestModelValidationProvider); var type = typeof(TestModelValidationProvider);
var typeActivator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService))) serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service); .Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var options = new MvcOptions(); var options = new MvcOptions();
options.ModelValidatorProviders.Add(type); options.ModelValidatorProviders.Add(type);
options.ModelValidatorProviders.Add(validationProvider); options.ModelValidatorProviders.Add(validationProvider);
@ -31,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
accessor.SetupGet(a => a.Options) accessor.SetupGet(a => a.Options)
.Returns(options); .Returns(options);
var provider = new DefaultModelValidatorProviderProvider(accessor.Object, var provider = new DefaultModelValidatorProviderProvider(accessor.Object,
typeActivator, typeActivatorCache,
serviceProvider.Object); serviceProvider.Object);
// Act // Act

View File

@ -3,7 +3,6 @@
using System; using System;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Moq; using Moq;
using Xunit; using Xunit;
@ -19,10 +18,10 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var service = Mock.Of<ITestService>(); var service = Mock.Of<ITestService>();
var valueProviderFactory = Mock.Of<IValueProviderFactory>(); var valueProviderFactory = Mock.Of<IValueProviderFactory>();
var type = typeof(TestValueProviderFactory); var type = typeof(TestValueProviderFactory);
var typeActivator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService))) serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service); .Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var options = new MvcOptions(); var options = new MvcOptions();
options.ValueProviderFactories.Add(valueProviderFactory); options.ValueProviderFactories.Add(valueProviderFactory);
options.ValueProviderFactories.Add(type); options.ValueProviderFactories.Add(type);
@ -30,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
accessor.SetupGet(a => a.Options) accessor.SetupGet(a => a.Options)
.Returns(options); .Returns(options);
var provider = new DefaultValueProviderFactoryProvider(accessor.Object, var provider = new DefaultValueProviderFactoryProvider(accessor.Object,
typeActivator, typeActivatorCache,
serviceProvider.Object); serviceProvider.Object);
// Act // Act

View File

@ -3,7 +3,6 @@
using System; using System;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Moq; using Moq;
using Xunit; using Xunit;
@ -19,17 +18,17 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var service = Mock.Of<ITestService>(); var service = Mock.Of<ITestService>();
var viewEngine = Mock.Of<IViewEngine>(); var viewEngine = Mock.Of<IViewEngine>();
var type = typeof(TestViewEngine); var type = typeof(TestViewEngine);
var typeActivator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService))) serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service); .Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var options = new MvcOptions(); var options = new MvcOptions();
options.ViewEngines.Add(viewEngine); options.ViewEngines.Add(viewEngine);
options.ViewEngines.Add(type); options.ViewEngines.Add(type);
var accessor = new Mock<IOptions<MvcOptions>>(); var accessor = new Mock<IOptions<MvcOptions>>();
accessor.SetupGet(a => a.Options) accessor.SetupGet(a => a.Options)
.Returns(options); .Returns(options);
var provider = new DefaultViewEngineProvider(accessor.Object, typeActivator, serviceProvider.Object); var provider = new DefaultViewEngineProvider(accessor.Object, typeActivatorCache, serviceProvider.Object);
// Act // Act
var result = provider.ViewEngines; var result = provider.ViewEngines;

View File

@ -74,17 +74,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
HttpContext = new DefaultHttpContext(), HttpContext = new DefaultHttpContext(),
}; };
var services = new Mock<IServiceProvider>();
var activator = new Mock<ITypeActivator>(MockBehavior.Strict);
activator
.Setup(a => a.CreateInstance(It.IsAny<IServiceProvider>(), typeof(TestProvider), It.IsAny<object[]>()))
.Returns(new TestProvider())
.Verifiable();
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
services
.Setup(s => s.GetService(typeof(ITypeActivator)))
.Returns(activator.Object);
context.OperationBindingContext.HttpContext.RequestServices = services.Object; context.OperationBindingContext.HttpContext.RequestServices = services.Object;
@ -109,16 +99,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
HttpContext = new DefaultHttpContext(), HttpContext = new DefaultHttpContext(),
}; };
var activator = new Mock<ITypeActivator>(MockBehavior.Strict);
activator
.Setup(a => a.CreateInstance(It.IsAny<IServiceProvider>(), typeof(TestProvider), It.IsAny<object[]>()))
.Returns(new TestProvider())
.Verifiable();
var services = new Mock<IServiceProvider>(MockBehavior.Strict); var services = new Mock<IServiceProvider>(MockBehavior.Strict);
services
.Setup(s => s.GetService(typeof(ITypeActivator)))
.Returns(activator.Object);
context.OperationBindingContext.HttpContext.RequestServices = services.Object; context.OperationBindingContext.HttpContext.RequestServices = services.Object;
@ -128,11 +109,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Assert // Assert
Assert.True(predicate(context, "UserName")); Assert.True(predicate(context, "UserName"));
Assert.True(predicate(context, "UserName")); Assert.True(predicate(context, "UserName"));
activator
.Verify(
a => a.CreateInstance(It.IsAny<IServiceProvider>(), typeof(TestProvider), It.IsAny<object[]>()),
Times.Once());
} }
#endif #endif

View File

@ -6,9 +6,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Http.Core;
using Microsoft.Framework.DependencyInjection;
using Moq; using Moq;
using Xunit; using Xunit;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
namespace Microsoft.AspNet.Mvc.ModelBinding.Test namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ {
@ -20,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
// Arrange // Arrange
var bindingContext = GetBindingContext(typeof(Person)); var bindingContext = GetBindingContext(typeof(Person));
var binder = new BinderTypeBasedModelBinder(Mock.Of<ITypeActivator>()); var binder = new BinderTypeBasedModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelAsync(bindingContext);
@ -36,14 +37,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var bindingContext = GetBindingContext(typeof(Person)); var bindingContext = GetBindingContext(typeof(Person));
bindingContext.ModelMetadata.BinderType = typeof(FalseModelBinder); bindingContext.ModelMetadata.BinderType = typeof(FalseModelBinder);
var innerModelBinder = new FalseModelBinder(); var binder = new BinderTypeBasedModelBinder();
var mockITypeActivator = new Mock<ITypeActivator>();
mockITypeActivator
.Setup(o => o.CreateInstance(It.IsAny<IServiceProvider>(), typeof(FalseModelBinder)))
.Returns(innerModelBinder);
var binder = new BinderTypeBasedModelBinder(mockITypeActivator.Object);
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelAsync(bindingContext);
@ -60,21 +54,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
bindingContext.ModelMetadata.BinderType = typeof(TrueModelBinder); bindingContext.ModelMetadata.BinderType = typeof(TrueModelBinder);
var model = new Person(); var model = new Person();
var innerModelBinder = new TrueModelBinder(model); var innerModelBinder = new TrueModelBinder();
var serviceProvider = new ServiceCollection()
.AddSingleton(typeof(IModelBinder))
.BuildServiceProvider();
var mockITypeActivator = new Mock<ITypeActivator>(); bindingContext.OperationBindingContext.HttpContext.RequestServices = serviceProvider;
mockITypeActivator
.Setup(o => o.CreateInstance(It.IsAny<IServiceProvider>(), typeof(TrueModelBinder)))
.Returns(innerModelBinder);
var binder = new BinderTypeBasedModelBinder(mockITypeActivator.Object); var binder = new BinderTypeBasedModelBinder();
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelAsync(bindingContext);
// Assert // Assert
var p = (Person)bindingContext.Model;
Assert.True(binderResult); Assert.True(binderResult);
Assert.Same(model, bindingContext.Model); Assert.Equal(model.Age, p.Age);
Assert.Equal(model.Name, p.Name);
} }
[Fact] [Fact]
@ -85,23 +81,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
bindingContext.ModelMetadata.BinderType = typeof(ModelBinderProvider); bindingContext.ModelMetadata.BinderType = typeof(ModelBinderProvider);
var model = new Person(); var model = new Person();
var innerModelBinder = new TrueModelBinder(model); var provider = new ModelBinderProvider();
var provider = new ModelBinderProvider(innerModelBinder); var serviceProvider = new ServiceCollection()
.AddSingleton(typeof(IModelBinderProvider))
.AddSingleton(typeof(IModelBinder))
.BuildServiceProvider();
var mockITypeActivator = new Mock<ITypeActivator>(); bindingContext.OperationBindingContext.HttpContext.RequestServices = serviceProvider;
mockITypeActivator var binder = new BinderTypeBasedModelBinder();
.Setup(o => o.CreateInstance(It.IsAny<IServiceProvider>(), typeof(ModelBinderProvider)))
.Returns(provider);
var binder = new BinderTypeBasedModelBinder(mockITypeActivator.Object);
// Act // Act
var binderResult = await binder.BindModelAsync(bindingContext); var binderResult = await binder.BindModelAsync(bindingContext);
// Assert // Assert
var p = (Person)bindingContext.Model;
Assert.True(binderResult); Assert.True(binderResult);
Assert.Same(model, bindingContext.Model); Assert.Equal(model.Age, p.Age);
Assert.Equal(model.Name, p.Name);
} }
[Fact] [Fact]
@ -109,10 +106,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ {
// Arrange // Arrange
var bindingContext = GetBindingContext(typeof(Person)); var bindingContext = GetBindingContext(typeof(Person));
bindingContext.ModelMetadata.BinderType = typeof(string); bindingContext.ModelMetadata.BinderType = typeof(Person);
var binder = new BinderTypeBasedModelBinder(Mock.Of<ITypeActivator>()); var binder = new BinderTypeBasedModelBinder();
var expected = "The type 'System.String' must implement either " + var expected = "The type '" + typeof(Person).FullName + "' must implement either " +
"'Microsoft.AspNet.Mvc.ModelBinding.IModelBinder' or " + "'Microsoft.AspNet.Mvc.ModelBinding.IModelBinder' or " +
"'Microsoft.AspNet.Mvc.ModelBinding.IModelBinderProvider' to be used as a model binder."; "'Microsoft.AspNet.Mvc.ModelBinding.IModelBinderProvider' to be used as a model binder.";
@ -165,9 +162,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ {
private readonly object _model; private readonly object _model;
public TrueModelBinder(object model) public TrueModelBinder()
{ {
_model = model; _model = new Person();
} }
public Task<bool> BindModelAsync(ModelBindingContext bindingContext) public Task<bool> BindModelAsync(ModelBindingContext bindingContext)
@ -181,9 +178,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{ {
private readonly IModelBinder _inner; private readonly IModelBinder _inner;
public ModelBinderProvider(IModelBinder inner) public ModelBinderProvider()
{ {
_inner = inner; var innerModelBinder = new TrueModelBinder();
_inner = innerModelBinder;
} }
public IReadOnlyList<IModelBinder> ModelBinders public IReadOnlyList<IModelBinder> ModelBinders

View File

@ -7,7 +7,6 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Framework.DependencyInjection;
using Moq; using Moq;
using Xunit; using Xunit;
@ -420,16 +419,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
private static CompositeModelBinder CreateBinderWithDefaults() private static CompositeModelBinder CreateBinderWithDefaults()
{ {
var serviceProvider = Mock.Of<IServiceProvider>();
var typeActivator = new Mock<ITypeActivator>();
typeActivator
.Setup(t => t.CreateInstance(serviceProvider, It.IsAny<Type>(), It.IsAny<object[]>()))
.Returns((IServiceProvider sp, Type t, object[] args) => Activator.CreateInstance(t));
var binders = new IModelBinder[] var binders = new IModelBinder[]
{ {
new TypeMatchModelBinder(), new TypeMatchModelBinder(),
new ByteArrayModelBinder(), new ByteArrayModelBinder(),
new GenericModelBinder(serviceProvider, typeActivator.Object), new GenericModelBinder(),
new ComplexModelDtoModelBinder(), new ComplexModelDtoModelBinder(),
new TypeConverterModelBinder(), new TypeConverterModelBinder(),
new MutableObjectModelBinder() new MutableObjectModelBinder()

View File

@ -11,7 +11,6 @@ using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Testing; using Microsoft.AspNet.Testing;
using Microsoft.Framework.DependencyInjection;
using Moq; using Moq;
using Xunit; using Xunit;
@ -1572,16 +1571,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private IServiceProvider CreateServices() private IServiceProvider CreateServices()
{ {
var services = new Mock<IServiceProvider>(MockBehavior.Strict); var services = new Mock<IServiceProvider>(MockBehavior.Strict);
var typeActivator = new Mock<ITypeActivator>(MockBehavior.Strict);
typeActivator
.Setup(f => f.CreateInstance(It.IsAny<IServiceProvider>(), typeof(ExcludedProvider)))
.Returns(new ExcludedProvider());
services
.Setup(s => s.GetService(typeof(ITypeActivator)))
.Returns(typeActivator.Object);
return services.Object; return services.Object;
} }

View File

@ -3,7 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Framework.DependencyInjection; using Microsoft.AspNet.Mvc.OptionDescriptors;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Moq; using Moq;
using Xunit; using Xunit;
@ -19,10 +19,10 @@ namespace Microsoft.AspNet.Mvc.Razor.OptionDescriptors
var service = Mock.Of<ITestService>(); var service = Mock.Of<ITestService>();
var expander = Mock.Of<IViewLocationExpander>(); var expander = Mock.Of<IViewLocationExpander>();
var type = typeof(TestViewLocationExpander); var type = typeof(TestViewLocationExpander);
var typeActivator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService))) serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service); .Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var options = new RazorViewEngineOptions(); var options = new RazorViewEngineOptions();
options.ViewLocationExpanders.Add(type); options.ViewLocationExpanders.Add(type);
options.ViewLocationExpanders.Add(expander); options.ViewLocationExpanders.Add(expander);
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.Razor.OptionDescriptors
accessor.SetupGet(a => a.Options) accessor.SetupGet(a => a.Options)
.Returns(options); .Returns(options);
var provider = new DefaultViewLocationExpanderProvider(accessor.Object, var provider = new DefaultViewLocationExpanderProvider(accessor.Object,
typeActivator, typeActivatorCache,
serviceProvider.Object); serviceProvider.Object);
// Act // Act

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public void Activate_ActivatesAndContextualizesPropertiesOnViews() public void Activate_ActivatesAndContextualizesPropertiesOnViews()
{ {
// Arrange // Arrange
var activator = new RazorPageActivator(Mock.Of<ITypeActivator>()); var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var instance = new TestRazorPage(); var instance = new TestRazorPage();
var myService = new MyService(); var myService = new MyService();
@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public void Activate_ThrowsIfTheViewDoesNotDeriveFromRazorViewOfT() public void Activate_ThrowsIfTheViewDoesNotDeriveFromRazorViewOfT()
{ {
// Arrange // Arrange
var activator = new RazorPageActivator(Mock.Of<ITypeActivator>()); var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var instance = new DoesNotDeriveFromRazorPageOfT(); var instance = new DoesNotDeriveFromRazorPageOfT();
var myService = new MyService(); var myService = new MyService();
@ -85,8 +85,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public void Activate_InstantiatesNewViewDataDictionaryType_IfTheTypeDoesNotMatch() public void Activate_InstantiatesNewViewDataDictionaryType_IfTheTypeDoesNotMatch()
{ {
// Arrange // Arrange
var typeActivator = new TypeActivator(); var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var activator = new RazorPageActivator(typeActivator);
var instance = new TestRazorPage(); var instance = new TestRazorPage();
var myService = new MyService(); var myService = new MyService();
@ -121,8 +120,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public void Activate_UsesPassedInViewDataDictionaryInstance_IfPassedInTypeMatches() public void Activate_UsesPassedInViewDataDictionaryInstance_IfPassedInTypeMatches()
{ {
// Arrange // Arrange
var typeActivator = new TypeActivator(); var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var activator = new RazorPageActivator(typeActivator);
var instance = new TestRazorPage(); var instance = new TestRazorPage();
var myService = new MyService(); var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>(); var helper = Mock.Of<IHtmlHelper<object>>();
@ -156,8 +154,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public void Activate_DeterminesModelTypeFromProperty() public void Activate_DeterminesModelTypeFromProperty()
{ {
// Arrange // Arrange
var typeActivator = new TypeActivator(); var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var activator = new RazorPageActivator(typeActivator);
var instance = new DoesNotDeriveFromRazorPageOfTButHasModelProperty(); var instance = new DoesNotDeriveFromRazorPageOfTButHasModelProperty();
var myService = new MyService(); var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>(); var helper = Mock.Of<IHtmlHelper<object>>();

View File

@ -72,14 +72,11 @@ namespace Microsoft.AspNet.Mvc.Razor
private static TestRazorPage CreateTestRazorPage() private static TestRazorPage CreateTestRazorPage()
{ {
var typeActivator = new TypeActivator(); var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var activator = new RazorPageActivator(typeActivator);
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
var myService = new MyService(); var myService = new MyService();
serviceProvider.Setup(mock => mock.GetService(typeof(MyService))) serviceProvider.Setup(mock => mock.GetService(typeof(MyService)))
.Returns(myService); .Returns(myService);
serviceProvider.Setup(mock => mock.GetService(typeof(ITypeActivator)))
.Returns(typeActivator);
serviceProvider.Setup(mock => mock.GetService(typeof(ITagHelperActivator))) serviceProvider.Setup(mock => mock.GetService(typeof(ITagHelperActivator)))
.Returns(new DefaultTagHelperActivator()); .Returns(new DefaultTagHelperActivator());
var httpContext = new Mock<HttpContext>(); var httpContext = new Mock<HttpContext>();

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
@ -11,6 +12,10 @@ namespace RequestServicesWebSite
public class RequestScopedActionConstraintAttribute : Attribute, IActionConstraintFactory public class RequestScopedActionConstraintAttribute : Attribute, IActionConstraintFactory
{ {
private readonly string _requestId; private readonly string _requestId;
private readonly Func<Type, object, ObjectFactory> CreateFactory =
(t, s) => ActivatorUtilities.CreateFactory(t, new[] { s.GetType() });
private readonly ConcurrentDictionary<Type, ObjectFactory> _constraintCache =
new ConcurrentDictionary<Type, ObjectFactory>();
public RequestScopedActionConstraintAttribute(string requestId) public RequestScopedActionConstraintAttribute(string requestId)
{ {
@ -19,8 +24,8 @@ namespace RequestServicesWebSite
public IActionConstraint CreateInstance(IServiceProvider services) public IActionConstraint CreateInstance(IServiceProvider services)
{ {
var activator = services.GetService<ITypeActivator>(); var constraintType = typeof(Constraint);
return activator.CreateInstance<Constraint>(services, _requestId); return (Constraint)ActivatorUtilities.CreateInstance(services, typeof(Constraint),new[] { _requestId });
} }
private class Constraint : IActionConstraint private class Constraint : IActionConstraint