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.
using System;
using System.Collections.Concurrent;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc
@ -12,17 +11,21 @@ namespace Microsoft.AspNet.Mvc
/// </summary>
public class DefaultControllerActivator : IControllerActivator
{
private static readonly Func<Type, ObjectFactory> _createControllerFactory =
type => ActivatorUtilities.CreateFactory(type, Type.EmptyTypes);
private readonly ConcurrentDictionary<Type, ObjectFactory> _controllerFactories =
new ConcurrentDictionary<Type, ObjectFactory>();
private readonly ITypeActivatorCache _typeActivatorCache;
/// <summary>
/// Creates a new <see cref="DefaultControllerActivator"/>.
/// </summary>
/// <param name="typeActivatorCache">The <see cref="ITypeActivatorCache"/>.</param>
public DefaultControllerActivator(ITypeActivatorCache typeActivatorCache)
{
_typeActivatorCache = typeActivatorCache;
}
/// <inheritdoc />
public object Create([NotNull] ActionContext actionContext, [NotNull] Type controllerType)
{
var factory = _controllerFactories.GetOrAdd(controllerType, _createControllerFactory);
return factory(actionContext.HttpContext.RequestServices, arguments: null);
var serviceProvider = actionContext.HttpContext.RequestServices;
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.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -14,16 +13,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
: OptionDescriptorBasedProvider<IExcludeTypeValidationFilter>, IValidationExcludeFiltersProvider
{
/// <summary>
/// Initializes a new instance of the DefaultBodyValidationExcludeFiltersProvider class.
/// Initializes a new instance of the <see cref="DefaultValidationExcludeFiltersProvider"/> class.
/// </summary>
/// <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="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param>
/// <param name="typeActivatorCache">The <see cref="ITypeActivatorCache"/> cache.</param>
/// <param name="serviceProvider">The <see cref="IServiceProvider"/>.</param>
public DefaultValidationExcludeFiltersProvider(IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ValidationExcludeFilters, typeActivator, serviceProvider)
ITypeActivatorCache typeActivatorCache,
IServiceProvider 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>
/// <returns>An <see cref="IFilter"/> representing the added type.</returns>
/// <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.
/// </remarks>
public static IFilter Add(
@ -37,7 +38,8 @@ namespace Microsoft.AspNet.Mvc
/// <param name="order">The order of the added filter.</param>
/// <returns>An <see cref="IFilter"/> representing the added type.</returns>
/// <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.
/// </remarks>
public static IFilter Add(

View File

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

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -16,13 +15,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the DefaultInputFormattersProvider class.
/// </summary>
/// <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
/// service collection.</param>
public DefaultInputFormattersProvider(IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.InputFormatters, typeActivator, serviceProvider)
: base(optionsAccessor.Options.InputFormatters, typeActivatorCache, serviceProvider)
{
}

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.OptionDescriptors;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc
@ -17,13 +16,14 @@ namespace Microsoft.AspNet.Mvc
/// Initializes a new instance of the DefaultOutputFormattersProvider class.
/// </summary>
/// <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
/// service collection.</param>
public DefaultOutputFormattersProvider(IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.OutputFormatters, typeActivator, serviceProvider)
ITypeActivatorCache typeActivatorCache,
IServiceProvider 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.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -16,14 +15,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the DefaultModelBindersProvider class.
/// </summary>
/// <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
/// service collection.</param>
public DefaultModelBindersProvider(
IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ModelBinders, typeActivator, serviceProvider)
: base(optionsAccessor.Options.ModelBinders, typeActivatorCache, serviceProvider)
{
}

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -17,14 +16,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultModelValidatorProviderProvider"/> class.
/// </summary>
/// <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
/// service collection.</param>
public DefaultModelValidatorProviderProvider(
IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ModelValidatorProviders, typeActivator, serviceProvider)
: base(optionsAccessor.Options.ModelValidatorProviders, typeActivatorCache, serviceProvider)
{
}

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -17,14 +16,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultValueProviderFactoryProvider"/> class.
/// </summary>
/// <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
/// service collection.</param>
public DefaultValueProviderFactoryProvider(
IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ValueProviderFactories, typeActivator, serviceProvider)
: base(optionsAccessor.Options.ValueProviderFactories, typeActivatorCache, serviceProvider)
{
}

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
@ -16,14 +15,15 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
/// Initializes a new instance of the <see cref="DefaultViewEngineProvider"/> class.
/// </summary>
/// <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
/// service collection.</param>
public DefaultViewEngineProvider(
IOptions<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
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>
{
private readonly IEnumerable<OptionDescriptor<TOption>> _optionDescriptors;
private readonly ITypeActivator _typeActivator;
private ITypeActivatorCache _typeActivatorCache;
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(
[NotNull] IEnumerable<OptionDescriptor<TOption>> optionDescriptors,
[NotNull] ITypeActivator typeActivator,
[NotNull] ITypeActivatorCache typeActivatorCache,
[NotNull] IServiceProvider serviceProvider)
{
_optionDescriptors = optionDescriptors;
_typeActivator = typeActivator;
_typeActivatorCache = typeActivatorCache;
_serviceProvider = serviceProvider;
}
@ -41,8 +49,7 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var instance = descriptor.Instance;
if (instance == null)
{
instance = (TOption)_typeActivator.CreateInstance(_serviceProvider,
descriptor.OptionType);
instance = _typeActivatorCache.CreateInstance<TOption>(_serviceProvider, descriptor.OptionType);
}
result.Add(instance);

View File

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

View File

@ -9,16 +9,16 @@ namespace Microsoft.AspNet.Mvc
public class DefaultViewComponentInvokerProvider : IViewComponentInvokerProvider
{
private readonly IServiceProvider _serviceProvider;
private readonly ITypeActivator _typeActivator;
private readonly ITypeActivatorCache _typeActivatorCache;
private readonly IViewComponentActivator _viewComponentActivator;
public DefaultViewComponentInvokerProvider(
IServiceProvider serviceProvider,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
IViewComponentActivator viewComponentActivator)
{
_serviceProvider = serviceProvider;
_typeActivator = typeActivator;
_typeActivatorCache = typeActivatorCache;
_viewComponentActivator = viewComponentActivator;
}
@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc
{
context.Result = new DefaultViewComponentInvoker(
_serviceProvider,
_typeActivator,
_typeActivatorCache,
_viewComponentActivator,
context.ComponentType,
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.
/// </remarks>
/// <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] IModelMetadataProvider metadataProvider,
[NotNull] ModelStateDictionary modelState)
@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Mvc
/// </para>
/// </remarks>
/// <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)
: base(source, declaredModelType: typeof(TModel))
{

View File

@ -17,6 +17,8 @@ namespace Microsoft.AspNet.Mvc
private static readonly Func<ModelBindingContext, string, bool> _defaultFilter =
(context, propertyName) => true;
private ObjectFactory _factory;
private Func<ModelBindingContext, string, bool> _predicateFromInclude;
/// <summary>
@ -79,7 +81,8 @@ namespace Microsoft.AspNet.Mvc
{
if (PredicateProviderType != null)
{
return CreatePredicateFromProviderType(PredicateProviderType);
var factory = GetFactory();
return CreatePredicateFromProviderType(factory);
}
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(
Type predicateProviderType)
ObjectFactory factory)
{
// Holding state to avoid execessive creation of the provider.
var initialized = false;
@ -110,11 +122,8 @@ namespace Microsoft.AspNet.Mvc
if (!initialized)
{
var services = context.OperationBindingContext.HttpContext.RequestServices;
var activator = services.GetService<ITypeActivator>();
var provider = (IPropertyBindingPredicateProvider)activator.CreateInstance(
services,
predicateProviderType);
var provider = (IPropertyBindingPredicateProvider)factory(services, arguments: null);
initialized = true;
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.
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.Framework.DependencyInjection;
@ -14,16 +15,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
/// </summary>
public class BinderTypeBasedModelBinder : IModelBinder
{
private readonly ITypeActivator _typeActivator;
/// <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;
}
private readonly Func<Type, ObjectFactory> _createFactory =
(t) => ActivatorUtilities.CreateFactory(t, Type.EmptyTypes);
private ConcurrentDictionary<Type, ObjectFactory> _typeActivatorCache =
new ConcurrentDictionary<Type, ObjectFactory>();
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
{
@ -35,8 +31,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
}
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;
if (modelBinder == null)
{

View File

@ -7,27 +7,17 @@ using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
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)
{
var binderType = ResolveBinderType(bindingContext.ModelType);
if (binderType != null)
{
var binder = (IModelBinder)_activator.CreateInstance(_serviceProvider, binderType);
var binder = (IModelBinder)Activator.CreateInstance(binderType);
await binder.BindModelAsync(bindingContext);
// 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.
/// </summary>
/// <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
/// service collection.</param>
public DefaultViewLocationExpanderProvider(
IOptions<RazorViewEngineOptions> optionsAccessor,
ITypeActivator typeActivator,
ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ViewLocationExpanders, typeActivator, serviceProvider)
: base(optionsAccessor.Options.ViewLocationExpanders, typeActivatorCache, serviceProvider)
{
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.Reflection;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
@ -14,16 +15,16 @@ namespace Microsoft.AspNet.Mvc.Razor
{
// Name of the "public TModel Model" property on RazorPage<TModel>
private const string ModelPropertyName = "Model";
private readonly ITypeActivator _typeActivator;
private readonly ConcurrentDictionary<Type, PageActivationInfo> _activationInfo;
private readonly IModelMetadataProvider _metadataProvider;
/// <summary>
/// Initializes a new instance of the <see cref="RazorPageActivator"/> class.
/// </summary>
public RazorPageActivator(ITypeActivator typeActivator)
public RazorPageActivator(IModelMetadataProvider metadataProvider)
{
_typeActivator = typeActivator;
_activationInfo = new ConcurrentDictionary<Type, PageActivationInfo>();
_metadataProvider = metadataProvider;
}
/// <inheritdoc />
@ -48,16 +49,15 @@ namespace Microsoft.AspNet.Mvc.Razor
if (context.ViewData == null)
{
// Create ViewDataDictionary<TModel>(IModelMetadataProvider, ModelStateDictionary).
return (ViewDataDictionary)_typeActivator.CreateInstance(context.HttpContext.RequestServices,
activationInfo.ViewDataDictionaryType,
context.ModelState);
return (ViewDataDictionary)Activator.CreateInstance(activationInfo.ViewDataDictionaryType,
_metadataProvider,
context.ModelState);
}
else if (context.ViewData.GetType() != activationInfo.ViewDataDictionaryType)
{
// Create ViewDataDictionary<TModel>(ViewDataDictionary).
return (ViewDataDictionary)_typeActivator.CreateInstance(context.HttpContext.RequestServices,
activationInfo.ViewDataDictionaryType,
context.ViewData);
return (ViewDataDictionary)Activator.CreateInstance(activationInfo.ViewDataDictionaryType,
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.
using System;
using System.Collections.Concurrent;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor
@ -12,16 +13,13 @@ namespace Microsoft.AspNet.Mvc.Razor
/// </summary>
public class VirtualPathRazorPageFactory : IRazorPageFactory
{
private readonly ITypeActivator _activator;
private readonly IServiceProvider _serviceProvider;
private readonly ICompilerCache _compilerCache;
private IRazorCompilationService _razorcompilationService;
public VirtualPathRazorPageFactory(ITypeActivator typeActivator,
IServiceProvider serviceProvider,
public VirtualPathRazorPageFactory(IServiceProvider serviceProvider,
ICompilerCache compilerCache)
{
_activator = typeActivator;
_serviceProvider = serviceProvider;
_compilerCache = compilerCache;
}
@ -60,10 +58,10 @@ namespace Microsoft.AspNet.Mvc.Razor
return null;
}
var page = (IRazorPage)_activator.CreateInstance(_serviceProvider, result.CompilationResult.CompiledType);
var page = (IRazorPage)Activator.CreateInstance(result.CompilationResult.CompiledType);
page.Path = relativePath;
return page;
}
}
}
}

View File

@ -37,8 +37,8 @@ namespace Microsoft.AspNet.Mvc
typeof(INestedProviderManagerAsync<>),
typeof(NestedProviderManagerAsync<>));
yield return describe.Transient<MvcMarkerService, MvcMarkerService>();
yield return describe.Singleton(typeof(ITypeActivatorCache), typeof(DefaultTypeActivatorCache));
yield return describe.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>));
// Core action discovery, filters and action execution.
// 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
yield return describe.Singleton<IControllerFactory, DefaultControllerFactory>();
// This has a cache, so it needs to be a singleton
yield return describe.Singleton<IControllerActivator, DefaultControllerActivator>();
yield return describe.Transient<IControllerActivator, DefaultControllerActivator>();
// This accesses per-reqest services
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<FormatFilter, FormatFilter>();
// Dataflow - ModelBinding, Validation and Formatting
// The DataAnnotationsModelMetadataProvider does significant caching of reflection/attributes
// and thus needs to be singleton.
yield return describe.Singleton<IModelMetadataProvider, DataAnnotationsModelMetadataProvider>();

View File

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

View File

@ -79,7 +79,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator());
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator());
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
@ -132,7 +132,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator());
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
@ -158,7 +158,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator());
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
@ -184,7 +184,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator());
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
@ -208,7 +208,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator());
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
@ -232,7 +232,7 @@ namespace Microsoft.AspNet.Mvc.Core
RequestServices = services
};
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
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>>();
optionsAccessor.SetupGet(o => o.Options)
.Returns(options);
var activator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.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
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.
using System;
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.OptionsModel;
using Moq;
using Xunit;
@ -22,11 +22,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options)
.Returns(options);
var activator = new TypeActivator();
var typeActivatorCache = new Mock<ITypeActivatorCache>();
var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator,
serviceProvider.Object);
typeActivatorCache.Object,
serviceProvider.Object);
// Act
var filters = provider.ExcludeFilters;
@ -47,11 +50,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options)
.Returns(options);
var activator = new TypeActivator();
var typeActivatorCache = new Mock<ITypeActivatorCache>();
var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator,
serviceProvider.Object);
typeActivatorCache.Object,
serviceProvider.Object);
// Act
var filters = provider.ExcludeFilters;
@ -72,11 +78,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options)
.Returns(options);
var activator = new TypeActivator();
var typeActivatorCache = new Mock<ITypeActivatorCache>();
var service = Mock.Of<ITestService>();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var provider = new DefaultValidationExcludeFiltersProvider(optionsAccessor.Object,
activator,
serviceProvider.Object);
typeActivatorCache.Object,
serviceProvider.Object);
// Act
var filters = provider.ExcludeFilters;
@ -98,11 +107,14 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var optionsAccessor = new Mock<IOptions<MvcOptions>>();
optionsAccessor.SetupGet(o => o.Options)
.Returns(options);
var activator = new TypeActivator();
var service = Mock.Of<ITestService>();
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,
activator,
serviceProvider.Object);
typeActivatorCache.Object,
serviceProvider.Object);
// Act
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.Collections.Generic;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
using Moq;
using Xunit;
@ -20,10 +19,10 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
var service = Mock.Of<ITestService>();
var validationProvider = Mock.Of<IModelValidatorProvider>();
var type = typeof(TestModelValidationProvider);
var typeActivator = new TypeActivator();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var options = new MvcOptions();
options.ModelValidatorProviders.Add(type);
options.ModelValidatorProviders.Add(validationProvider);
@ -31,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors
accessor.SetupGet(a => a.Options)
.Returns(options);
var provider = new DefaultModelValidatorProviderProvider(accessor.Object,
typeActivator,
typeActivatorCache,
serviceProvider.Object);
// Act

View File

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

View File

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

View File

@ -74,18 +74,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
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);
services
.Setup(s => s.GetService(typeof(ITypeActivator)))
.Returns(activator.Object);
var services = new Mock<IServiceProvider>();
context.OperationBindingContext.HttpContext.RequestServices = services.Object;
// Act
@ -109,17 +99,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
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);
services
.Setup(s => s.GetService(typeof(ITypeActivator)))
.Returns(activator.Object);
context.OperationBindingContext.HttpContext.RequestServices = services.Object;
// Act
@ -128,11 +109,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Assert
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

View File

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

View File

@ -7,7 +7,6 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Framework.DependencyInjection;
using Moq;
using Xunit;
@ -420,16 +419,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
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[]
{
new TypeMatchModelBinder(),
new ByteArrayModelBinder(),
new GenericModelBinder(serviceProvider, typeActivator.Object),
new GenericModelBinder(),
new ComplexModelDtoModelBinder(),
new TypeConverterModelBinder(),
new MutableObjectModelBinder()

View File

@ -11,7 +11,6 @@ using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Testing;
using Microsoft.Framework.DependencyInjection;
using Moq;
using Xunit;
@ -1572,16 +1571,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private IServiceProvider CreateServices()
{
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;
}

View File

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

View File

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

View File

@ -72,14 +72,11 @@ namespace Microsoft.AspNet.Mvc.Razor
private static TestRazorPage CreateTestRazorPage()
{
var typeActivator = new TypeActivator();
var activator = new RazorPageActivator(typeActivator);
var activator = new RazorPageActivator(new EmptyModelMetadataProvider());
var serviceProvider = new Mock<IServiceProvider>();
var myService = new MyService();
serviceProvider.Setup(mock => mock.GetService(typeof(MyService)))
.Returns(myService);
serviceProvider.Setup(mock => mock.GetService(typeof(ITypeActivator)))
.Returns(typeActivator);
serviceProvider.Setup(mock => mock.GetService(typeof(ITagHelperActivator)))
.Returns(new DefaultTagHelperActivator());
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.
using System;
using System.Collections.Concurrent;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.DependencyInjection;
@ -11,6 +12,10 @@ namespace RequestServicesWebSite
public class RequestScopedActionConstraintAttribute : Attribute, IActionConstraintFactory
{
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)
{
@ -19,8 +24,8 @@ namespace RequestServicesWebSite
public IActionConstraint CreateInstance(IServiceProvider services)
{
var activator = services.GetService<ITypeActivator>();
return activator.CreateInstance<Constraint>(services, _requestId);
var constraintType = typeof(Constraint);
return (Constraint)ActivatorUtilities.CreateInstance(services, typeof(Constraint),new[] { _requestId });
}
private class Constraint : IActionConstraint