diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs index 25f7eafea8..1172508a18 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs @@ -2,13 +2,10 @@ // 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.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.AspNet.Mvc.Core; -using Microsoft.AspNet.Mvc.ModelBinding; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultFilterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultFilterProvider.cs index ee3363507c..6d2c0ae413 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultFilterProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultFilterProvider.cs @@ -10,18 +10,11 @@ namespace Microsoft.AspNet.Mvc.Filters { public class DefaultFilterProvider : IFilterProvider { - public DefaultFilterProvider(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - public int Order { get { return DefaultOrder.DefaultFrameworkSortOrder; } } - protected IServiceProvider ServiceProvider { get; private set; } - /// public void OnProvidersExecuting([NotNull] FilterProviderContext context) { @@ -55,7 +48,8 @@ namespace Microsoft.AspNet.Mvc.Filters } else { - filterItem.Filter = filterFactory.CreateInstance(ServiceProvider); + var services = context.ActionContext.HttpContext.RequestServices; + filterItem.Filter = filterFactory.CreateInstance(services); if (filterItem.Filter == null) { diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcCoreServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcCoreServiceCollectionExtensions.cs index d32fac2abc..2db49214df 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcCoreServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcCoreServiceCollectionExtensions.cs @@ -88,13 +88,15 @@ namespace Microsoft.Framework.DependencyInjection // // Action Invoker // - // This accesses per-request services + // These two access per-request services services.TryAddTransient(); - services.TryAddTransient(); services.TryAddEnumerable( ServiceDescriptor.Transient()); + + // These are stateless + services.TryAddSingleton(); services.TryAddEnumerable( - ServiceDescriptor.Transient()); + ServiceDescriptor.Singleton()); // // ModelBinding, Validation and Formatting @@ -106,7 +108,7 @@ namespace Microsoft.Framework.DependencyInjection var options = serviceProvider.GetRequiredService>().Options; return new DefaultCompositeMetadataDetailsProvider(options.ModelMetadataDetailsProviders); })); - services.TryAdd(ServiceDescriptor.Transient(serviceProvider => + services.TryAdd(ServiceDescriptor.Singleton(serviceProvider => { var options = serviceProvider.GetRequiredService>().Options; var modelMetadataProvider = serviceProvider.GetRequiredService(); @@ -125,7 +127,7 @@ namespace Microsoft.Framework.DependencyInjection // // Random Infrastructure // - services.TryAddTransient(); + services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddScoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)); services.TryAddScoped(); @@ -141,4 +143,4 @@ namespace Microsoft.Framework.DependencyInjection ServiceDescriptor.Transient, MvcRouteOptionsSetup>()); } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentHelper.cs b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentHelper.cs index 7ef13e5b0d..79986ecbac 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentHelper.cs @@ -132,14 +132,15 @@ namespace Microsoft.AspNet.Mvc.ViewComponents [NotNull] ViewComponentDescriptor descriptor, object[] arguments) { - var invoker = _invokerFactory.CreateInstance(descriptor, arguments); + var context = new ViewComponentContext(descriptor, arguments, _viewContext, writer); + + var invoker = _invokerFactory.CreateInstance(context); if (invoker == null) { throw new InvalidOperationException( Resources.FormatViewComponent_IViewComponentFactory_ReturnedNull(descriptor.Type.FullName)); } - var context = new ViewComponentContext(descriptor, arguments, _viewContext, writer); await invoker.InvokeAsync(context); } @@ -148,14 +149,15 @@ namespace Microsoft.AspNet.Mvc.ViewComponents [NotNull] ViewComponentDescriptor descriptor, object[] arguments) { - var invoker = _invokerFactory.CreateInstance(descriptor, arguments); + var context = new ViewComponentContext(descriptor, arguments, _viewContext, writer); + + var invoker = _invokerFactory.CreateInstance(context); if (invoker == null) { throw new InvalidOperationException( Resources.FormatViewComponent_IViewComponentFactory_ReturnedNull(descriptor.Type.FullName)); } - var context = new ViewComponentContext(descriptor, arguments, _viewContext, writer); invoker.Invoke(context); } } diff --git a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvoker.cs b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvoker.cs index 865c459769..afb1a59fd1 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvoker.cs @@ -13,16 +13,13 @@ namespace Microsoft.AspNet.Mvc.ViewComponents { public class DefaultViewComponentInvoker : IViewComponentInvoker { - private readonly IServiceProvider _serviceProvider; private readonly ITypeActivatorCache _typeActivatorCache; private readonly IViewComponentActivator _viewComponentActivator; public DefaultViewComponentInvoker( - [NotNull] IServiceProvider serviceProvider, [NotNull] ITypeActivatorCache typeActivatorCache, [NotNull] IViewComponentActivator viewComponentActivator) { - _serviceProvider = serviceProvider; _typeActivatorCache = typeActivatorCache; _viewComponentActivator = viewComponentActivator; } @@ -77,8 +74,9 @@ namespace Microsoft.AspNet.Mvc.ViewComponents private object CreateComponent([NotNull] ViewComponentContext context) { + var services = context.ViewContext.HttpContext.RequestServices; var component = _typeActivatorCache.CreateInstance( - _serviceProvider, + services, context.ViewComponentDescriptor.Type); _viewComponentActivator.Activate(component, context); return component; diff --git a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvokerFactory.cs b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvokerFactory.cs index 880acbb650..41bbd98a87 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvokerFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/DefaultViewComponentInvokerFactory.cs @@ -1,23 +1,19 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ViewComponents { public class DefaultViewComponentInvokerFactory : IViewComponentInvokerFactory { - private readonly IServiceProvider _serviceProvider; private readonly ITypeActivatorCache _typeActivatorCache; private readonly IViewComponentActivator _viewComponentActivator; public DefaultViewComponentInvokerFactory( - IServiceProvider serviceProvider, ITypeActivatorCache typeActivatorCache, IViewComponentActivator viewComponentActivator) { - _serviceProvider = serviceProvider; _typeActivatorCache = typeActivatorCache; _viewComponentActivator = viewComponentActivator; } @@ -26,12 +22,9 @@ namespace Microsoft.AspNet.Mvc.ViewComponents // We don't currently make use of the descriptor or the arguments here (they are available on the context). // We might do this some day to cache which method we select, so resist the urge to 'clean' this without // considering that possibility. - public IViewComponentInvoker CreateInstance( - [NotNull] ViewComponentDescriptor viewComponentDescriptor, - object[] args) + public IViewComponentInvoker CreateInstance([NotNull] ViewComponentContext context) { return new DefaultViewComponentInvoker( - _serviceProvider, _typeActivatorCache, _viewComponentActivator); } diff --git a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/IViewComponentInvokerFactory.cs b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/IViewComponentInvokerFactory.cs index 5477d431aa..726da7c7bd 100644 --- a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/IViewComponentInvokerFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/IViewComponentInvokerFactory.cs @@ -7,8 +7,6 @@ namespace Microsoft.AspNet.Mvc.ViewComponents { public interface IViewComponentInvokerFactory { - IViewComponentInvoker CreateInstance( - [NotNull] ViewComponentDescriptor viewComponentDescriptor, - object[] args); + IViewComponentInvoker CreateInstance([NotNull] ViewComponentContext context); } } diff --git a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs index 806decbd4f..b5deb66160 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServiceCollectionExtensions.cs @@ -222,7 +222,7 @@ namespace Microsoft.Framework.DependencyInjection // View and rendering helpers services.TryAddTransient(); services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)); - services.TryAddTransient(); + services.TryAddSingleton(); // Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict. services.TryAddSingleton(); @@ -230,9 +230,9 @@ namespace Microsoft.Framework.DependencyInjection // Consumed by the Cache tag helper to cache results across the lifetime of the application. services.TryAddSingleton(); - // DefaultHtmlGenerator is pretty much stateless but depends on Scoped services such as IUrlHelper and - // IActionBindingContextProvider. Therefore it too is scoped. - services.TryAddTransient(); + // DefaultHtmlGenerator is pretty much stateless but depends on IUrlHelper, which is scoped. + // Therefore it too is scoped. + services.TryAddScoped(); // These do caching so they should stay singleton services.TryAddSingleton(); @@ -242,7 +242,7 @@ namespace Microsoft.Framework.DependencyInjection DefaultViewComponentDescriptorCollectionProvider>(); services.TryAddTransient(); - services.TryAddTransient(); + services.TryAddSingleton(); services.TryAddTransient(); // Security and Authorization @@ -292,4 +292,4 @@ namespace Microsoft.Framework.DependencyInjection services.AddWebEncoders(); } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultFilterProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultFilterProviderTest.cs index da5215f970..66fff9b790 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultFilterProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultFilterProviderTest.cs @@ -137,9 +137,7 @@ namespace Microsoft.AspNet.Mvc.Filters private DefaultFilterProvider CreateProvider() { - var services = new ServiceContainer(); - - return new DefaultFilterProvider(services); + return new DefaultFilterProvider(); } private FilterProviderContext CreateFilterContext(List items)