首页 > 其他分享 >庆军之热拔插系统--action路径的问题

庆军之热拔插系统--action路径的问题

时间:2022-11-19 23:56:35浏览次数:63  
标签:-- app 庆军 热拔 controller action services using public

过程,controller下的路由是怎么来的。最后落到了,DefaultApplicationModelProvider下面的CreateActionModel,

参考来自此,(78条消息) .netcore入门13:aspnetcore源码之如何在程序启动时将Controller里的Action自动扫描封装成Endpoint_jackletter的博客-CSDN博客

 

一、探索目的说明
我们知道在程序启动时,程序就会扫描所有相关程序集中Controller的Action,然后将他们封装成一个个的Endpoint交给“路由”模块去管理,这样在http请求到来时“路由”模块才能寻找到正确的Endpoint,进而找到Action并调用执行。这里我们正是要探索“程序在启动时如何扫描Action并封装成Endpoint”的。
————————————————
版权声明:本文为CSDN博主「jackletter」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010476739/article/details/104545284

 

正常的Controller的Action怎么变成Endpoint的。

services.AddControllers()--->ActionDescriptor 

MvcCoreServiceCollectionExtensions.cs

services.TryAddEnumerable(
ServiceDescriptor.Transient<IApplicationModelProvider, DefaultApplicationModelProvider>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<IApplicationModelProvider, ApiBehaviorApplicationModelProvider>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<IActionDescriptorProvider, ControllerActionDescriptorProvider>());

ControllerActionDescriptorProvider->ControllerActionDescriptorBuilder

endpoints.MapControllers()--->EndPoint

热拔插系统,会通知修改,在change之后,会upEndPoint

我的问题是怎么修改 EndPoint 的路由。

重写DefaultApplicationModelProvider,不太现实。在bing里面翻了半天。突然看到

https://www.vb-net.com/AspNet-DocAndSamples-2017/aspnetcore/mvc/controllers/application-model.htm

 

下面一个例子

Sample: Custom Routing Convention

You can use an IApplicationModelConvention to customize how routing works. For example, the following convention will incorporate Controllers’ namespaces into their routes, replacing . in the namespace with / in the route:

[!code-csharpMain]

   1:  using Microsoft.AspNetCore.Mvc.ApplicationModels;
   2:  using System.Linq;
   3:   
   4:  namespace AppModelSample.Conventions
   5:  {
   6:      public class NamespaceRoutingConvention : IApplicationModelConvention
   7:      {
   8:          public void Apply(ApplicationModel application)
   9:          {
  10:              foreach (var controller in application.Controllers)
  11:              {
  12:                  var hasAttributeRouteModels = controller.Selectors
  13:                      .Any(selector => selector.AttributeRouteModel != null);
  14:   
  15:                  if (!hasAttributeRouteModels
  16:                      && controller.ControllerName.Contains("Namespace")) // affect one controller in this sample
  17:                  {
  18:                      // Replace the . in the namespace with a / to create the attribute route
  19:                      // Ex: MySite.Admin namespace will correspond to MySite/Admin attribute route
  20:                      // Then attach [controller], [action] and optional {id?} token.
  21:                      // [Controller] and [action] is replaced with the controller and action
  22:                      // name to generate the final template
  23:                      controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
  24:                      {
  25:                          Template = controller.ControllerType.Namespace.Replace('.', '/') + "/[controller]/[action]/{id?}"
  26:                      };
  27:                  }
  28:              }
  29:   
  30:              // You can continue to put attribute route templates for the controller actions depending on the way you want them to behave
  31:          }
  32:      }
  33:  }

 

The convention is added as an option in Startup.

[!code-csharpMain]

   1:  using AppModelSample.Conventions;
   2:  using Microsoft.AspNetCore.Builder;
   3:  using Microsoft.AspNetCore.Hosting;
   4:  using Microsoft.Extensions.Configuration;
   5:  using Microsoft.Extensions.DependencyInjection;
   6:  using Microsoft.Extensions.Logging;
   7:   
   8:  namespace AppModelSample
   9:  {
  10:      public class Startup
  11:      {
  12:          public Startup(IHostingEnvironment env)
  13:          {
  14:              var builder = new ConfigurationBuilder()
  15:                  .SetBasePath(env.ContentRootPath)
  16:                  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  17:                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
  18:                  .AddEnvironmentVariables();
  19:              Configuration = builder.Build();
  20:          }
  21:   
  22:          public IConfigurationRoot Configuration { get; }
  23:   
  24:          // This method gets called by the runtime. Use this method to add services to the container.
  25:          #region ConfigureServices
  26:          public void ConfigureServices(IServiceCollection services)
  27:          {
  28:              services.AddMvc(options =>
  29:              {
  30:                  options.Conventions.Add(new ApplicationDescription("My Application Description"));
  31:                  options.Conventions.Add(new NamespaceRoutingConvention());
  32:                  //options.Conventions.Add(new IdsMustBeInRouteParameterModelConvention());
  33:              });
  34:          }
  35:          #endregion
  36:   
  37:          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  38:          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  39:          {
  40:              loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  41:              loggerFactory.AddDebug();
  42:   
  43:              if (env.IsDevelopment())
  44:              {
  45:                  app.UseDeveloperExceptionPage();
  46:                  app.UseBrowserLink();
  47:              }
  48:              else
  49:              {
  50:                  app.UseExceptionHandler("/Home/Error");
  51:              }
  52:   
  53:              app.UseStaticFiles();
  54:   
  55:              app.UseMvc(routes =>
  56:              {
  57:                  routes.MapRoute(
  58:                      name: "default",
  59:                      template: "{controller=Home}/{action=Index}/{id?}");
  60:              });
  61:          }
  62:      }
  63:  }

 

[!TIP] You can add conventions to your (xref:)middleware by accessing MvcOptions using services.Configure<MvcOptions>(c => c.Conventions.Add(YOURCONVENTION));

This sample applies this convention to routes that are not using attribute routing where the controller has “Namespace” in its name. The following controller demonstrates this convention:

[!code-csharpMain]

ControllerActionDescriptorBuilder->ApplicationModelFactory->ApplicationModelConventions->IApplicationModelProvider

解决了我的问题。

根据dll的名称来 改变路由。

代码的确是很复杂。

标签:--,app,庆军,热拔,controller,action,services,using,public
From: https://www.cnblogs.com/forhell/p/16907566.html

相关文章

  • AWS资源注解
    EC2(ElasticComputeCloud)ECS(ElasticContainerService)ECR(ElasticContainerRegistry)Lambdahttps://aws.amazon.com/lambda/RunyourCodeinResponset......
  • 二、结构型模式
    07.适配器模式Target:目标抽象类,此处是接口,客户需要用的特定接口;Adapter:适配器类,关联适配者类,实现目标抽象类接口;Adaptee:适配者类,被适配的角色,与Target不兼容的类,这个......
  • “当时”与“当前”
    先举个例子:电商系统,用户下单可以使用卡券支付。此时,订单的金额会有两部分构成:商品金额和卡券抵扣金额。通常,这样的信息在订单详情页也会展示出来。那么,我们的订单表里,关......
  • 2022-11-19学习内容-Server端代码编写-Client端代码编写
    1.Server端代码编写1.1UserDBHelper.javapackagecom.example.chapter07_server.database;importandroid.content.Context;importandroid.database.sqlite.SQLiteD......
  • Spring源码循环依赖
    一级缓存:存储单例Bean的Map对象。二级缓存:为了将成熟Bean和纯净Bean分离开来,职责更明确,代码更容易维护,避免由于多线程的环境下读取到不完整的Bean。二级缓存不能存储原生......
  • 还在手撸TCP/UDP/COM通信?一个仅16K的库搞定!
    摘要在一些项目中,可能会用到串口(COM)通信,也可能会使用TCP-Server,TCP-Client,UDP等等,这种实现起来都大差不差,所以我封装了一个无任何依赖小而美的通信框架,通用性强,安全稳......
  • mysql索引的排列顺序
    索引的排序是按照定义索引的顺序来的索引的顺序要遵循三个规则要遵循最左前缀无论是多个还是一个列的索引都不应该跳过最左列如果在查询语句当中没有使用最左前缀的字......
  • <原文转载> 自定义博客园博客页面鼠标
    1、鼠标指针替换在博客设置->文件中上传自己的鼠标样式,上传时注意将后缀改为.ico对刚刚上传的ico文件右键->复制链接地址添加css代码在博客设置->设置中找到页面......
  • Android 利用和风天气API显示实时天气
    最近开发遇到了这样的需求,需要在APP中显示出实时天气等信息,可以利用和风天气提供的API,免费订阅可以使用一定数量的查询额度,不过也差不多够用了。进入和风天气官网,注册。......
  • django---中间件
    中间件当用户发送请求时,其实时候是将请求发送给wsgi(一种协议),django使用的是wsgiref,然后再将请求发送给django的各个中间件(settings里的MIDDLEWARE表示使用的中间件),再由......