65.9K
CodeProject 正在变化。 阅读更多。
Home

在 ASP.NET 5 应用程序中使用 Service

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.63/5 (6投票s)

2016年1月11日

CPOL

3分钟阅读

viewsIcon

15658

在 ASP.NET 5 应用程序中使用 Service

引言

我们知道在 ASP.NET 5 中,整个框架都被重写了。 ASP.NET 5 不依赖于旧的庞大的 System.Web.dll。 这意味着它不依赖于特定的托管环境。 现在 (ASP.NET 5) 框架变得非常精简和可插拔。 那么这意味着什么呢? 它的意思是,ASP.NET 5 中将只附带非常有限的功能,如果用户需要更多功能,他们可以轻松地插入框架。 默认情况下,MVC 框架不随 ASP.NET 5 一起提供,如果我们想使用 MVC,我们必须在 ASP.NET 5 上插入 MVC service。 这种机制非常简单,你只需要在 Startup.csproject.json 文件中添加几行代码即可。 如果你打开任何脚手架 Startup.cs 文件,它将包含两个方法,分别是 ConfigureServiceConfigure 方法。

    public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }
        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
        }

我们可以从 ConfigureServiceConfigure 函数中调用 AddMvc()UseMvc() 扩展方法来在应用程序中钩住 MVC。 在本文中,我们将深入研究 AddMvc() 函数,并讨论 MvcServiceCollectionExtensions 类,该类包含 AddMvc() 和一些有用的方法,用于在 ASP.NET 5 应用程序中钩住和配置 MVC。

MvcServiceCollectionExtensions 类的位置在 Microsoft.Framework.DependencyInjection 命名空间中

    namespace Microsoft.Framework.DependencyInjection
    {
        public static class MvcServiceCollectionExtensions
        {
        }
    }

并且该类包含以下方法。

其中 AddMvcServices()ConfigureDefaultServices() 是内部且私有的。 如果你只是在 Visual Studio 中打开该类,那么默认情况下你可能看不到这些函数,但它对某些反汇编工具是可见的。 现在我们已经看到我们使用 AddMvc() 函数在 ASP.NET 应用程序中添加 MVC services,让我们检查一下 AddMvc() 函数的定义,看看当我们向 ASP.NET 应用程序添加 MVC 框架时到底发生了什么。 这是 AddMvc() 函数的定义。

    public static IServiceCollection AddMvc(this [NotNull] IServiceCollection services)
    {
        ConfigureDefaultServices(services);
        AddMvcServices(services);
        return services;
    }

我们看到,在内部,AddMvc() 扩展方法调用了 ConfigureDefaultService()AddMvcServices() 这两个内部和私有函数。 所以让我们检查一下这两个函数的定义。 这是 ConfigureDefaultServices() 函数的定义。

    private static void ConfigureDefaultServices(IServiceCollection services)
    {
        OptionsServiceCollectionExtensions.AddOptions(services);
        DataProtectionServiceCollectionExtensions.AddDataProtection(services);
        RoutingServices.AddRouting(services);
        CorsServiceCollectionExtensions.AddCors(services);
        ServiceCollectionExtensions.AddAuthorization(services);
        EncoderServiceCollectionExtensions.AddWebEncoders(services);
        OptionsServiceCollectionExtensions.Configure<RouteOptions>(services, routeOptions => routeOptions.get_ConstraintMap().Add("exists", typeof(KnownRouteValueConstraint)), 0, "");
    }

我们看到,在这个函数中,MVC 框架的一些默认服务,如路由、CORS、授权,都被添加到了应用程序中。 这些是使用有限功能的 MVC 应用程序启动和运行的最小服务。 然后它调用 AddServices() 函数来添加其他 MVC 功能。 它包含大量 MVC 功能。

internal static void AddMvcServices(IServiceCollection services)
{
    ServiceCollectionExtensions.AddTransient<IConfigureOptions<MvcOptions>, MvcOptionsSetup>(services);
    ServiceCollectionExtensions.AddTransient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>(services);
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IAssemblyProvider, DefaultAssemblyProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<MvcMarkerService, MvcMarkerService>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<ITypeActivatorCache, DefaultTypeActivatorCache>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)));
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IControllerTypeProvider, DefaultControllerTypeProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IControllerModelBuilder, DefaultControllerModelBuilder>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IActionModelBuilder, DefaultActionModelBuilder>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IControllerFactory, DefaultControllerFactory>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IControllerActivator, DefaultControllerActivator>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IActionInvokerFactory, ActionInvokerFactory>());
    ServiceCollectionExtensions.AddTransient<IActionConstraintProvider, DefaultActionConstraintProvider>(services);
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IActionSelector, DefaultActionSelector>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IObjectModelValidator>(serviceProvider => new DefaultObjectValidator(ServiceProviderExtensions.GetRequiredService<IOptions<MvcOptions>>(serviceProvider).get_Options().get_ValidationExcludeFilters(), ServiceProviderExtensions.GetRequiredService<IModelMetadataProvider>(serviceProvider))));
    ServiceCollectionExtensions.AddTransient<IActionDescriptorProvider, ControllerActionDescriptorProvider>(services);
    ServiceCollectionExtensions.AddTransient<IActionInvokerProvider, ControllerActionInvokerProvider>(services);
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IActionDescriptorsCollectionProvider, DefaultActionDescriptorsCollectionProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IGlobalFilterProvider, DefaultGlobalFilterProvider>());
    ServiceCollectionExtensions.AddTransient<IFilterProvider, DefaultFilterProvider>(services);
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<FormatFilter, FormatFilter>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<CorsAuthorizationFilter, CorsAuthorizationFilter>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IModelMetadataProvider, DefaultModelMetadataProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<ICompositeMetadataDetailsProvider>(serviceProvider => new DefaultCompositeMetadataDetailsProvider(ServiceProviderExtensions.GetRequiredService<IOptions<MvcOptions>>(serviceProvider).get_Options().get_ModelMetadataDetailsProviders())));
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<JsonOutputFormatter>(serviceProvider => new JsonOutputFormatter(ServiceProviderExtensions.GetRequiredService<IOptions<MvcOptions>>(serviceProvider).get_Options().get_SerializerSettings())));
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Scoped<ICompositeViewEngine, CompositeViewEngine>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IViewLocationCache, DefaultViewLocationCache>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<ICodeTreeCache>(serviceProvider => new DefaultCodeTreeCache(ServiceProviderExtensions.GetRequiredService<IOptions<RazorViewEngineOptions>>(serviceProvider).get_Options().get_FileProvider())));
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IMvcRazorHost, MvcRazorHost>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<ICompilerCache, CompilerCache>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<ICompilationService, RoslynCompilationService>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IRazorCompilationService, RazorCompilationService>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Scoped<IViewStartProvider, ViewStartProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IRazorViewFactory, RazorViewFactory>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IRazorPageActivator, RazorPageActivator>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Scoped<IRazorPageFactory, VirtualPathRazorPageFactory>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IHtmlHelper, HtmlHelper>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)));
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IJsonHelper, JsonHelper>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Scoped<IUrlHelper, UrlHelper>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<ITagHelperActivator, DefaultTagHelperActivator>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IMemoryCache, MemoryCache>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IHtmlGenerator, DefaultHtmlGenerator>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IViewComponentSelector, DefaultViewComponentSelector>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IViewComponentActivator, DefaultViewComponentActivator>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IViewComponentDescriptorCollectionProvider, DefaultViewComponentDescriptorCollectionProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IViewComponentDescriptorProvider, DefaultViewComponentDescriptorProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Transient<IViewComponentHelper, DefaultViewComponentHelper>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IClaimUidExtractor, DefaultClaimUidExtractor>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<AntiForgery, AntiForgery>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IAntiForgeryAdditionalDataProvider, DefaultAntiForgeryAdditionalDataProvider>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<IApiDescriptionGroupCollectionProvider, ApiDescriptionGroupCollectionProvider>());
    ServiceCollectionExtensions.AddTransient<IApiDescriptionProvider, DefaultApiDescriptionProvider>(services);
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Scoped<ITempDataDictionary, TempDataDictionary>());
    ServiceCollectionExtensions.TryAdd(services, ServiceDescriptor.Singleton<ITempDataProvider, SessionStateTempDataProvider>());
}

然后它返回 IServiceCollection 的同一个实例。 所以现在很清楚的是,当我们调用 AddMvc() 函数时,所有与 MVC 相关的功能都会被添加到 ASP.NET 5 应用程序中。 现在可能出现的问题是,如果我们想更改任何 MVC 功能呢? MvcServiceCollectionExtensions 类包含 ConfigureMvc() 函数,我们可以在其中更改已添加到应用程序中的任何 MVC 功能。 在此示例中,我们将尝试在视图引擎中进行更改,并了解 ConfigureMvc() 函数的功能。 这是修改后的 ConfigureServices() 函数,我们在 ConfigureMvc() 部分中删除了默认的视图引擎。

    public void ConfigureServices(IServiceCollection services)
    {
                services.AddMvc();
                services.ConfigureMvc(f =>
                {
                    f.ViewEngines.RemoveAt(0);
                });
    }

这意味着在当前应用程序中没有视图引擎来处理视图。 现在让我们向某个控制器执行一个 HTTP 请求,我们将遇到以下错误。

我相信并验证了所有路由相关的东西、控制器和视图,而且都已经就位,错误是由于在 ConfigureMvc() 部分中删除了视图引擎。 现在,你只需要更改现有的行为,就可以在同一部分中注册自定义过滤器和服务。 以下是我们可以更改默认行为的几个属性。

结论

在本文中,我们学习了在 ASP.NET 5 应用程序中设置 MVC 和默认 MVC services。 这些设置和行为是纯粹面向需求和特定于应用程序的。 请记住,仅添加 MVC services 并不能在应用程序中启用 MVC,我们需要在 Configure() 中调用 UseMvc() 扩展方法。

© . All rights reserved.