// To enable unit testing
        internal static void AddMvcCoreServices(IServiceCollection services)
        {
            //
            // Options
            //
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IConfigureOptions <MvcOptions>, MvcCoreMvcOptionsSetup>());
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IConfigureOptions <RouteOptions>, MvcCoreRouteOptionsSetup>());

            //
            // Action Discovery
            //
            // These are consumed only when creating action descriptors, then they can be de-allocated
            services.TryAddTransient <IAssemblyProvider, DefaultAssemblyProvider>();
            services.TryAddTransient <IControllerTypeProvider, DefaultControllerTypeProvider>();
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IApplicationModelProvider, DefaultApplicationModelProvider>());
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IActionDescriptorProvider, ControllerActionDescriptorProvider>());
            services.TryAddSingleton <IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>();

            //
            // Action Selection
            //
            services.TryAddSingleton <IActionSelector, DefaultActionSelector>();

            // Performs caching
            services.TryAddSingleton <IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>();

            // Will be cached by the DefaultActionSelector
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IActionConstraintProvider, DefaultActionConstraintProvider>());

            //
            // Controller Factory
            //
            // This has a cache, so it needs to be a singleton
            services.TryAddSingleton <IControllerFactory, DefaultControllerFactory>();

            // Will be cached by the DefaultControllerFactory
            services.TryAddTransient <IControllerActivator, DefaultControllerActivator>();
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IControllerPropertyActivator, DefaultControllerPropertyActivator>());

            //
            // Action Invoker
            //
            // The IActionInvokerFactory is cachable
            services.TryAddSingleton <IActionInvokerFactory, ActionInvokerFactory>();
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IActionInvokerProvider, ControllerActionInvokerProvider>());

            // These are stateless
            services.TryAddSingleton <IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>();
            services.TryAddEnumerable(
                ServiceDescriptor.Singleton <IFilterProvider, DefaultFilterProvider>());

            //
            // ModelBinding, Validation and Formatting
            //
            // The DefaultModelMetadataProvider does significant caching and should be a singleton.
            services.TryAddSingleton <IModelMetadataProvider, DefaultModelMetadataProvider>();
            services.TryAdd(ServiceDescriptor.Transient <ICompositeMetadataDetailsProvider>(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <IOptions <MvcOptions> >().Value;
                return(new DefaultCompositeMetadataDetailsProvider(options.ModelMetadataDetailsProviders));
            }));
            services.TryAdd(ServiceDescriptor.Singleton <IObjectModelValidator>(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <IOptions <MvcOptions> >().Value;
                var modelMetadataProvider = serviceProvider.GetRequiredService <IModelMetadataProvider>();
                return(new DefaultObjectValidator(options.ValidationExcludeFilters, modelMetadataProvider));
            }));

            //
            // Random Infrastructure
            //
            services.TryAddSingleton <MvcMarkerService, MvcMarkerService>();
            services.TryAddSingleton <ITypeActivatorCache, DefaultTypeActivatorCache>();
            services.TryAddSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.TryAddSingleton <IActionBindingContextAccessor, ActionBindingContextAccessor>();
            services.TryAddSingleton <IUrlHelper, UrlHelper>();
        }
Esempio n. 2
0
 // Internal for testing.
 internal static void AddJsonFormatterServices(IServiceCollection services)
 {
     services.TryAddEnumerable(
         ServiceDescriptor.Transient <IConfigureOptions <MvcOptions>, MvcJsonMvcOptionsSetup>());
 }
        // To enable unit testing
        internal static void AddMvcServices(IServiceCollection services)
        {
            // Options and core services.
            // multiple registration service
            services.AddTransient <IConfigureOptions <MvcOptions>, MvcOptionsSetup>();
            // multiple registration service
            services.AddTransient <IConfigureOptions <RazorViewEngineOptions>, RazorViewEngineOptionsSetup>();

            services.TryAdd(ServiceDescriptor.Transient <IAssemblyProvider, DefaultAssemblyProvider>());

            services.TryAdd(ServiceDescriptor.Transient <MvcMarkerService, MvcMarkerService>());
            services.TryAdd((ServiceDescriptor.Singleton <ITypeActivatorCache, DefaultTypeActivatorCache>()));
            services.TryAdd(ServiceDescriptor.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
            services.TryAdd(ServiceDescriptor.Transient <IControllerTypeProvider, DefaultControllerTypeProvider>());
            services.TryAdd(ServiceDescriptor.Transient <IControllerModelBuilder, DefaultControllerModelBuilder>());
            services.TryAdd(ServiceDescriptor.Transient <IActionModelBuilder, DefaultActionModelBuilder>());

            // This has a cache, so it needs to be a singleton
            services.TryAdd(ServiceDescriptor.Singleton <IControllerFactory, DefaultControllerFactory>());

            services.TryAdd(ServiceDescriptor.Transient <IControllerActivator, DefaultControllerActivator>());

            // This accesses per-request services
            services.TryAdd(ServiceDescriptor.Transient <IActionInvokerFactory, ActionInvokerFactory>());

            // This provider needs access to the per-request services, but might be used many times for a given
            // request.
            // multiple registration service
            services.AddTransient <IActionConstraintProvider, DefaultActionConstraintProvider>();

            services.TryAdd(ServiceDescriptor
                            .Singleton <IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>());
            services.TryAdd(ServiceDescriptor.Singleton <IActionSelector, DefaultActionSelector>());
            services.TryAdd(ServiceDescriptor
                            .Transient <IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>());
            services.TryAdd(ServiceDescriptor.Transient <IObjectModelValidator>(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <IOptions <MvcOptions> >().Options;
                var modelMetadataProvider = serviceProvider.GetRequiredService <IModelMetadataProvider>();
                return(new DefaultObjectValidator(options.ValidationExcludeFilters, modelMetadataProvider));
            }));

            // multiple registration service
            services.AddTransient <IActionDescriptorProvider, ControllerActionDescriptorProvider>();

            // multiple registration service
            services.AddTransient <IActionInvokerProvider, ControllerActionInvokerProvider>();

            services.TryAdd(ServiceDescriptor
                            .Singleton <IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>());

            // The IGlobalFilterProvider is used to build the action descriptors (likely once) and so should
            // remain transient to avoid keeping it in memory.
            services.TryAdd(ServiceDescriptor.Transient <IGlobalFilterProvider, DefaultGlobalFilterProvider>());
            // multiple registration service
            services.AddTransient <IFilterProvider, DefaultFilterProvider>();

            services.TryAdd(ServiceDescriptor.Transient <FormatFilter, FormatFilter>());
            services.TryAdd(ServiceDescriptor.Transient <CorsAuthorizationFilter, CorsAuthorizationFilter>());

            // Dataflow - ModelBinding, Validation and Formatting
            //
            // The DefaultModelMetadataProvider does significant caching and should be a singleton.
            services.TryAdd(ServiceDescriptor.Singleton <IModelMetadataProvider, DefaultModelMetadataProvider>());
            services.TryAdd(ServiceDescriptor.Transient <ICompositeMetadataDetailsProvider>(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <IOptions <MvcOptions> >().Options;
                return(new DefaultCompositeMetadataDetailsProvider(options.ModelMetadataDetailsProviders));
            }));

            // JsonOutputFormatter should use the SerializerSettings on MvcOptions
            services.TryAdd(ServiceDescriptor.Singleton <JsonOutputFormatter>(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <IOptions <MvcOptions> >().Options;
                return(new JsonOutputFormatter(options.SerializerSettings));
            }));

            // Razor, Views and runtime compilation

            // The provider is inexpensive to initialize and provides ViewEngines that may require request
            // specific services.
            services.TryAdd(ServiceDescriptor.Scoped <ICompositeViewEngine, CompositeViewEngine>());

            // Caches view locations that are valid for the lifetime of the application.
            services.TryAdd(ServiceDescriptor.Singleton <IViewLocationCache, DefaultViewLocationCache>());
            services.TryAdd(ServiceDescriptor.Singleton <ICodeTreeCache>(serviceProvider =>
            {
                var cachedFileProvider = serviceProvider.GetRequiredService <IOptions <RazorViewEngineOptions> >();
                return(new DefaultCodeTreeCache(cachedFileProvider.Options.FileProvider));
            }));

            // The host is designed to be discarded after consumption and is very inexpensive to initialize.
            services.TryAdd(ServiceDescriptor.Transient <IMvcRazorHost, MvcRazorHost>());

            // Caches compilation artifacts across the lifetime of the application.
            services.TryAdd(ServiceDescriptor.Singleton <ICompilerCache, CompilerCache>());

            // This caches compilation related details that are valid across the lifetime of the application
            // and is required to be a singleton.
            services.TryAdd(ServiceDescriptor.Singleton <ICompilationService, RoslynCompilationService>());

            // Both the compiler cache and roslyn compilation service hold on the compilation related
            // caches. RazorCompilation service is just an adapter service, and it is transient to ensure
            // the IMvcRazorHost dependency does not maintain state.
            services.TryAdd(ServiceDescriptor.Transient <IRazorCompilationService, RazorCompilationService>());

            // The ViewStartProvider needs to be able to consume scoped instances of IRazorPageFactory
            services.TryAdd(ServiceDescriptor.Scoped <IViewStartProvider, ViewStartProvider>());
            services.TryAdd(ServiceDescriptor.Transient <IRazorViewFactory, RazorViewFactory>());
            services.TryAdd(ServiceDescriptor.Singleton <IRazorPageActivator, RazorPageActivator>());

            // Virtual path view factory needs to stay scoped so views can get get scoped services.
            services.TryAdd(ServiceDescriptor.Scoped <IRazorPageFactory, VirtualPathRazorPageFactory>());

            // View and rendering helpers
            services.TryAdd(ServiceDescriptor.Transient <IHtmlHelper, HtmlHelper>());
            services.TryAdd(ServiceDescriptor.Transient(typeof(IHtmlHelper <>), typeof(HtmlHelper <>)));
            services.TryAdd(ServiceDescriptor.Transient <IJsonHelper, JsonHelper>());
            services.TryAdd(ServiceDescriptor.Scoped <IUrlHelper, UrlHelper>());

            // Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict.
            services.TryAdd(ServiceDescriptor.Singleton <ITagHelperActivator, DefaultTagHelperActivator>());

            // Consumed by the Cache tag helper to cache results across the lifetime of the application.
            services.TryAdd(ServiceDescriptor.Singleton <IMemoryCache, MemoryCache>());

            // DefaultHtmlGenerator is pretty much stateless but depends on Scoped services such as IUrlHelper and
            // IActionBindingContextProvider. Therefore it too is scoped.
            services.TryAdd(ServiceDescriptor.Transient <IHtmlGenerator, DefaultHtmlGenerator>());

            // These do caching so they should stay singleton
            services.TryAdd(ServiceDescriptor.Singleton <IViewComponentSelector, DefaultViewComponentSelector>());
            services.TryAdd(ServiceDescriptor.Singleton <IViewComponentActivator, DefaultViewComponentActivator>());
            services.TryAdd(ServiceDescriptor.Singleton <
                                IViewComponentDescriptorCollectionProvider,
                                DefaultViewComponentDescriptorCollectionProvider>());

            services.TryAdd(ServiceDescriptor
                            .Transient <IViewComponentDescriptorProvider, DefaultViewComponentDescriptorProvider>());
            services.TryAdd(ServiceDescriptor
                            .Transient <IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>());
            services.TryAdd(ServiceDescriptor.Transient <IViewComponentHelper, DefaultViewComponentHelper>());

            // Security and Authorization
            services.TryAdd(ServiceDescriptor.Singleton <IClaimUidExtractor, DefaultClaimUidExtractor>());
            services.TryAdd(ServiceDescriptor.Singleton <AntiForgery, AntiForgery>());
            services.TryAdd(ServiceDescriptor
                            .Singleton <IAntiForgeryAdditionalDataProvider, DefaultAntiForgeryAdditionalDataProvider>());

            // Api Description
            services.TryAdd(ServiceDescriptor
                            .Singleton <IApiDescriptionGroupCollectionProvider, ApiDescriptionGroupCollectionProvider>());
            // multiple registration service
            services.AddTransient <IApiDescriptionProvider, DefaultApiDescriptionProvider>();

            // Temp Data
            services.TryAdd(ServiceDescriptor.Scoped <ITempDataDictionary, TempDataDictionary>());
            // This does caching so it should stay singleton
            services.TryAdd(ServiceDescriptor.Singleton <ITempDataProvider, SessionStateTempDataProvider>());
        }
 // Internal for testing.
 internal static void AddXmlDataContractSerializerFormatterServices(IServiceCollection services)
 {
     services.TryAddEnumerable(
         ServiceDescriptor.Transient <IConfigureOptions <MvcOptions>, MvcXmlDataContractSerializerMvcOptionsSetup>());
 }
 // Internal for testing.
 internal static void AddApiExplorerServices(IServiceCollection services)
 {
     services.TryAddSingleton <IApiDescriptionGroupCollectionProvider, ApiDescriptionGroupCollectionProvider>();
     services.TryAddEnumerable(
         ServiceDescriptor.Transient <IApiDescriptionProvider, DefaultApiDescriptionProvider>());
 }
Esempio n. 6
0
        public static IdentityBuilder AddIdentity <TUser, TRole>(
            this IServiceCollection services,
            Action <IdentityOptions> configureOptions)
            where TUser : class
            where TRole : class
        {
            // Services used by identity
            services.AddOptions();
            services.AddDataProtection();
            services.AddLogging();
            services.TryAdd(ServiceDescriptor.Singleton <IHttpContextAccessor, HttpContextAccessor>());

            // Identity services
            services.TryAdd(ServiceDescriptor.Transient <IUserValidator <TUser>, UserValidator <TUser> >());
            services.TryAdd(ServiceDescriptor.Transient <IPasswordValidator <TUser>, PasswordValidator <TUser> >());
            services.TryAdd(ServiceDescriptor.Transient <IPasswordHasher <TUser>, PasswordHasher <TUser> >());
            services.TryAdd(ServiceDescriptor.Transient <ILookupNormalizer, UpperInvariantLookupNormalizer>());
            services.TryAdd(ServiceDescriptor.Transient <IRoleValidator <TRole>, RoleValidator <TRole> >());
            // No interface for the error describer so we can add errors without rev'ing the interface
            services.TryAdd(ServiceDescriptor.Transient <IdentityErrorDescriber, IdentityErrorDescriber>());
            services.TryAdd(ServiceDescriptor.Scoped <ISecurityStampValidator, SecurityStampValidator <TUser> >());
            services.TryAdd(ServiceDescriptor.Scoped <IUserClaimsPrincipalFactory <TUser>, UserClaimsPrincipalFactory <TUser, TRole> >());
            services.TryAdd(ServiceDescriptor.Scoped <UserManager <TUser>, UserManager <TUser> >());
            services.TryAdd(ServiceDescriptor.Scoped <SignInManager <TUser>, SignInManager <TUser> >());
            services.TryAdd(ServiceDescriptor.Scoped <RoleManager <TRole>, RoleManager <TRole> >());

            if (configureOptions != null)
            {
                services.ConfigureIdentity(configureOptions);
            }
            services.Configure <ExternalAuthenticationOptions>(options =>
            {
                options.SignInScheme = IdentityOptions.ExternalCookieAuthenticationScheme;
            });

            // Configure all of the cookie middlewares
            services.ConfigureIdentityApplicationCookie(options =>
            {
                options.AuthenticationScheme    = IdentityOptions.ApplicationCookieAuthenticationScheme;
                options.AutomaticAuthentication = true;
                options.LoginPath     = new PathString("/Account/Login");
                options.Notifications = new CookieAuthenticationNotifications
                {
                    OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
                };
            });
            services.Configure <CookieAuthenticationOptions>(options =>
            {
                options.AuthenticationScheme    = IdentityOptions.ExternalCookieAuthenticationScheme;
                options.AutomaticAuthentication = false;
                options.CookieName     = IdentityOptions.ExternalCookieAuthenticationScheme;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
            }, IdentityOptions.ExternalCookieAuthenticationScheme);
            services.Configure <CookieAuthenticationOptions>(options =>
            {
                options.AuthenticationScheme    = IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme;
                options.AutomaticAuthentication = false;
                options.CookieName = IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme;
            }, IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
            services.Configure <CookieAuthenticationOptions>(options =>
            {
                options.AuthenticationScheme    = IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme;
                options.AutomaticAuthentication = false;
                options.CookieName     = IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
            }, IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);

            return(new IdentityBuilder(typeof(TUser), typeof(TRole), services));
        }
 public static IServiceCollection AddRouting(this IServiceCollection services)
 {
     services.AddOptions();
     services.TryAdd(ServiceDescriptor.Transient <IInlineConstraintResolver, DefaultInlineConstraintResolver>());
     return(services);
 }
Esempio n. 8
0
 // Internal for testing.
 internal static void AddDataAnnotationsServices(IServiceCollection services)
 {
     services.TryAddEnumerable(
         ServiceDescriptor.Transient <IConfigureOptions <MvcOptions>, MvcDataAnnotationsMvcOptionsSetup>());
 }
Esempio n. 9
0
        // Internal for testing.
        internal static void AddViewServices(IServiceCollection services)
        {
            services.AddDataProtection();
            services.AddAntiforgery();
            services.AddWebEncoders();

            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IConfigureOptions <MvcViewOptions>, MvcViewOptionsSetup>());
            services.TryAddEnumerable(
                ServiceDescriptor.Transient <IConfigureOptions <MvcOptions>, TempDataMvcOptionsSetup>());

            //
            // View Engine and related infrastructure
            //
            services.TryAddSingleton <ICompositeViewEngine, CompositeViewEngine>();

            // Support for activating ViewDataDictionary
            services.TryAddEnumerable(
                ServiceDescriptor
                .Transient <IControllerPropertyActivator, ViewDataDictionaryControllerPropertyActivator>());

            //
            // HTML Helper
            //
            services.TryAddTransient <IHtmlHelper, HtmlHelper>();
            services.TryAddTransient(typeof(IHtmlHelper <>), typeof(HtmlHelper <>));

            // DefaultHtmlGenerator is pretty much stateless but depends on IUrlHelper, which is scoped.
            // Therefore it too is scoped.
            services.TryAddScoped <IHtmlGenerator, DefaultHtmlGenerator>();

            //
            // JSON Helper
            //
            services.TryAddSingleton <IJsonHelper, JsonHelper>();
            services.TryAdd(ServiceDescriptor.Singleton <JsonOutputFormatter>(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <IOptions <MvcJsonOptions> >().Options;
                return(new JsonOutputFormatter(options.SerializerSettings));
            }));

            //
            // View Components
            //
            // These do caching so they should stay singleton
            services.TryAddSingleton <IViewComponentSelector, DefaultViewComponentSelector>();
            services.TryAddSingleton <IViewComponentActivator, DefaultViewComponentActivator>();
            services.TryAddSingleton <
                IViewComponentDescriptorCollectionProvider,
                DefaultViewComponentDescriptorCollectionProvider>();

            services.TryAddTransient <IViewComponentDescriptorProvider, DefaultViewComponentDescriptorProvider>();
            services.TryAddSingleton <IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>();
            services.TryAddTransient <IViewComponentHelper, DefaultViewComponentHelper>();

            //
            // Temp Data
            //
            // Holds per-request data so it should be scoped
            services.TryAddScoped <ITempDataDictionary, TempDataDictionary>();
            services.TryAddScoped <SaveTempDataFilter>();

            // This does caching so it should stay singleton
            services.TryAddSingleton <ITempDataProvider, SessionStateTempDataProvider>();
        }