上一篇博客中,讲到了将WebApi Host到控制台和IIS,本篇总结一下如何将WebApi的Service以插件的形式进行动态部署,并设置Hoster的首页显示Api帮助文档,当然,也包括动态部署进来的插件的Api帮助。


话不多说,上酸菜,啊不, 上干货。

源码地址

  1. 建立Host

    新建 Asp.Net Web Application, 解决方案名称填写WeiApiPluginDemo,项目名称填写IISHost,确定

选择 Empty, 确定

菜单中点选 Tools -> NuGet Package Manager -> Package Manager Console

控制台中输入

Install-Package Microsoft.AspNet.WebApi.HelpPage

将会在IISHost项目中增加Area目录以及目录下的一大坨目录和文件,暂且放下不管,等会我们再来配置和编码。

鼠标右键点击IISHost项目,Add -> Global Application Class, 建立全局配置文件, 在弹出的 Specify Name for Item 窗体中点击 OK, 使用默认的 Item name

Global.asax.cs 中, 删掉除 Application_Start 外的其他方法(这里用不到)

添加代码如下:

      protected void Application_Start(object sender, EventArgs e)
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
 鼠标右键点击IISHost项目,*Add -> New Folder*, 建立名为 *App_Start* 的目录,右键点击新建的目录,*Add->Class*, 新建名为 *RouteConfig.cs* 的类.

 最终代码如下, 注意添加相关引用。
```csharp
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
``` 鼠标右键点击 *App_Start* 目录,*Add->Class*, 新建名为 *WebApiConfig.cs* 的类,添加 *Register* 方法
```csharp
public static void Register(HttpConfiguration config)
{
config.Services.Replace(typeof(IAssembliesResolver), new PluginsAssembliesResolver()); config.MapHttpAttributeRoutes(); config.EnableCors(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
```

在项目根目录中新建一个名为 WebSettingsConfig 的辅助类

    public class WebSettingsConfig
{
public static string plugin_location
{
get
{
return AppSettingValue();
}
} private static string AppSettingValue([CallerMemberName] string key = null)
{
return ConfigurationManager.AppSettings[key];
}
}

web.config 配置, 确保 bin/plugins 目录存在,这个目录是将来我们存放插件的地方

   <configuration>
<appSettings>
<!--插件目录-->
<add key="plugin_location" value="~/bin/plugins"/>
</appSettings>
...

回到 Global.asax.cs, 添加对 RouteConfig 的命名空间引用

右键点击 App_Start 目录,新建名为 PluginsAssembliesResolver 的类,该类负责解析插件(dll)

代码如下:

      ```csharp
/// <summary>
/// 发现非引用Dll中的Controller,意即插件
/// </summary>
public class PluginsAssembliesResolver : DefaultAssembliesResolver
{
public virtual ICollection<Assembly> GetAssemblies()
{
ICollection<Assembly> baseAssemblies = base.GetAssemblies();
var mp = HttpContext.Current.Server.MapPath(WebSettingsConfig.plugin_location); foreach (string file in Directory.GetFiles(mp, "*.dll"))
{
var controllersAssembly = Assembly.LoadFile(file);
baseAssemblies.Add(controllersAssembly);
} List<Assembly> assemblies = new List<Assembly>(baseAssemblies);
return assemblies; }
}

鼠标右键点击 IISHost 项目,Add -> New Folder, 建立名为 Controllers 的目录,右键点击新建的目录,Add -> Controller...,在弹出的 Add Scaffold 窗体中选择 MVC5 Controller * Empty,点击 Add,在 Add Controller 窗体将新的 Controller 命名为 HomeController

替换 HomeController.cs 中的 Index() 内容,最后代码长这样

     public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return RedirectToAction("Index", "Help"); //替换原来的 return View();
}
}

删掉系统自动创建的 Views 目录

打开 IISHost 项目中的 Areas->HelpPage->App_Start->HelpPageConfig.cs, 在 Register 方法中添加如下代码

     public static void Register(HttpConfiguration config)
{
//添加
config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath(WebSettingsConfig.plugin_location)));
}

HelpPageConfig.cs 的上一级目录下(也就是HelpPage目录下)新建名为 MultiXmlDocumentationProvider.cs 的 class

该类实现 IDocumentationProvider, IModelDocumentationProvider 两个接口,具体代码如下:

    public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
//说白了就是查找目录下的所有Xml文档,加载到 _documentationProviders 中
private IList<XmlDocumentationProvider> _documentationProviders; public MultiXmlDocumentationProvider(string xmlDocFilesPath)
{
_documentationProviders = new List<XmlDocumentationProvider>(); foreach (string file in Directory.GetFiles(xmlDocFilesPath, "*.xml"))
{
_documentationProviders.Add(new XmlDocumentationProvider(file));
}
} public string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
return _documentationProviders.Select(x => x.GetDocumentation(parameterDescriptor)).FirstOrDefault(x => !string.IsNullOrEmpty(x));
} public string GetDocumentation(Type type)
{
return _documentationProviders.Select(x => x.GetDocumentation(type)).FirstOrDefault(x => !string.IsNullOrEmpty(x));
} //成员导航
public string GetDocumentation(MemberInfo member)
{
return _documentationProviders
.Select(x => x.GetDocumentation(member))
.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x));
} //action 描述
public string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
return _documentationProviders.Select(x => x.GetDocumentation(actionDescriptor)).FirstOrDefault(x => !string.IsNullOrEmpty(x));
} //Controller 描述
public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)
{
return _documentationProviders.Select(x => x.GetDocumentation(controllerDescriptor)).FirstOrDefault(x => !string.IsNullOrEmpty(x));
} public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)
{
return _documentationProviders.Select(x => x.GetDocumentation(actionDescriptor)).FirstOrDefault(x => !string.IsNullOrEmpty(x)); }
}

编译项目 IISHost 确保没有错误

  1. 建立类库项目若干

右键点击解决方案, 新建类库,命名为 DemoClass01

菜单中点选 Tools -> NuGet Package Manager -> Package Manager Console

控制台中输入

    Install-Package Microsoft.AspNet.WebApi.Core

在项目 DemoClass01 中新建目录 Controllers 并新建 Controllers\DemoClass01.cs, 代码如下:

    /// <summary>
/// 测试DemoClass01
/// </summary>
[RoutePrefix("demo")]
public class DemoController : ApiController
{
/// <summary>
/// 测试方法1
/// </summary>
/// <returns></returns>
[HttpGet, Route("get1")]
public HttpResponseMessage Get()
{
return Request.CreateResponse("demo class 01 response");
}
}

右键单击项目 Properties->Build 勾选 XML documentation file 项。

如法炮制,可以多建立几个类似的项目供测试。

  1. 测试

发布或者直接使用IISExpress运行(确保插件目录已存在,并将步骤2中的类库生成的Dll文件和Xml文件拷贝至插件目录)

测试结果如下:

源码地址

插件式WebApi服务及自动生成Api帮助文档的更多相关文章

  1. SpringBoot + Swagger2 自动生成API接口文档

    spring-boot作为当前最为流行的Java web开发脚手架,相信越来越多的开发者会使用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于移动端 ...

  2. 利用ShowDoc自动生成api接口文档

    最近在做新项目,感觉写完一个接口 还要去再写一遍api文档 挺浪费时间的,所以借用ShowDoc的api开放功能 自动生成api文档. 首先 去 https://www.showdoc.cc/ 注册一 ...

  3. Spring MVC学习总结(9)——Spring MVC整合swagger自动生成api接口文档

    Swagger 号称:世界最流行的API框架,官网:http://swagger.io/,Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总 ...

  4. spring boot使用swagger生成api接口文档

    前言 在之前的文章中,使用mybatis-plus生成了对应的包,在此基础上,我们针对项目的api接口,添加swagger配置和注解,生成swagger接口文档 具体可以查看本站spring boot ...

  5. vite插件-自动生成vue组件文档

    特点 支持热更新 快速启动,依赖于 vite,无需另起服务 自动生成组件导航 ui 采用了vant-ui的样式 核心方法覆盖率达到了 92.86% 使用 yarn add vite-plugin-vu ...

  6. Spring Boot2配置Swagger2生成API接口文档

    一.Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 及时性 (接 ...

  7. [ python3 ] 基于zabbix 自动生成xlsx监控文档

    准备做一个每周自动的巡检报告,数据来源于zabbix,通过python读取zabbix数据库获取数据并制作成excel表格, 本来打算直接邮件发送到指定邮箱,但是都被SMTP过滤掉了,试过126和QQ ...

  8. MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误

    今天照着孙鑫老师的VC++教程学习文件的操作,VS2010,单文档应用程序,项目文件命名为File,也就有了自动生成的CFileDoc.CFileView等类,一进去就编译运行(就是最初自动生成的项目 ...

  9. 【2016.3.30项目技术记录】]VS2010自动生成MFC单文档框架程序的修改:去除属性框,在CViewTree类中添加鼠标单击响应

    转自http://blog.csdn.net/yanfeiouc2009/archive/2010/06/07/5653360.aspx 手头上有个东西要用到单文档,由于想省事,直接用VS2010做了 ...

随机推荐

  1. python中mysql的存储

    1. 连接mysql import pymysql db = pymysql.connect(host=', port=3306) cursor = db.cursor() cursor.execut ...

  2. Google 里的软件工程学

    简评:原文作者 Fergus Henderson 在 Google 工作了 10 年以上,目前负责 Google 的 text-tospeech 工程小组.有很多书籍或文章会从 商业/管理 等非技术角 ...

  3. delphi 10.2---非常简单的数组用法求和

    unit Unit9; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  4. 【Qt开发】实现系统托盘,托盘菜单,托盘消息

    概述 系统托盘就是在系统桌面底部特定的区域显示运行的程序.windows在任务栏状态区域,linux在布告栏区域.应用程序系统托盘功能,是比较普遍的功能,本篇将详细的介绍如何实现该功能. 演示Demo ...

  5. 线性表中顺序表的的理解和实现(java)

    线性表的顺序表示指的是用一组地址连续的存储单元以此存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像.通常,称这种存储结构的线性表为顺序表.特点是:逻辑上相邻的数据元素,其物理次序上也 ...

  6. PHPStudy环境下搭建composer

    第一种方法(亲测有效) 1. 找到composer的安装目录:D:\phpstudy\PHPTutorial\tools\composer 2.把目录下的 composer.bat 和 compose ...

  7. python学习,day4:生成器

    1.生成器:只有在调用是才会生成相应的数据.(比较省内存,它只保留当时生成的.而列表会保存整个列表) a = [i*2 for i in range(10)] #列表生成式 print(a) 这样会把 ...

  8. 二分难题 && deque

    141. Sqrt(x) https://www.lintcode.com/problem/sqrtx/description?_from=ladder&&fromId=4 publi ...

  9. mac下抓包工具charles

    图片没带过来,想看截图的可以直接点击有道云笔记的链接: http://note.youdao.com/share/?id=f5c7369a0c1e1e37cdcd08a04d33be7e 1.下载 h ...

  10. (转)多种方法实现Loading(加载)动画效果

    当我们ajax提交一个按钮的时候,给那个按钮来个Loading效果会高端很多,体验也会上升个层次. 既能让用户知道正在提交中,也能防止二次提交,好处多多呢.