上一篇博客中,讲到了将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. [Flex] 组件Tree系列 —— 打开和关闭节点

    mxm: <?xml version="1.0" encoding="utf-8"?> <!--功能描述:打开和关闭节点--> < ...

  2. [CISCO] Telete/SSH 之 Port 绑定/端口安全

    [网络] Telete/SSH 之 Port 绑定/端口安全 一.前言 之前写完了网络] DHCP 之 Mac 绑定,CiSCO 交换机配置 SSH 登陆.这次我们再试试能不能挖的在深入些. (1) ...

  3. 爬虫5:beautifulsoup

      灵活方便的网页解析库,处理高效,支持多种解析器,利用它不用编写正则表达式即可方便的实现网页信息的提取     一. BeautifulSoup的几种解析库   解析器 使用方法 优势 劣势 Pyt ...

  4. Modbus通用数据读取工具设计及使用

    一.公共功能码定义 二.能读取的数据类型 1.bit类型,比如01功能码,读到的就是位的状态,是ON 还是OFF,也就是对应着0或1. 2.byte类型,比如03功能码. 3.short类型,比如03 ...

  5. 多并发编程基础 之线程程 Thried

    原贴 https://www.cnblogs.com/gbq-dog/p/10365669.html 今日要整理的内容有 1. 操作系统中线程理论 2.python中的GIL锁 3.线程在python ...

  6. hive连接mysql遇到的问题

    启动hive之前应该先启动metastore,也是在bin目录下:./hive --service metastore &然后再启动hive: ./hive 今天连接hive时总是报错:Una ...

  7. leetcode-350-Intersection of Two Arrays II(求两个数组的交集)

    题目描述: Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, ...

  8. C#-集合及特殊集合——★★哈希表集合★★

    集合的基本信息: System.Collections命名空间包含接口和类,这些接口和类定义各种对象(如列表.队列.位组数.哈希表和字典)的集合. System.Collections.Generic ...

  9. 使用Chrome-headless模式下,截屏不全屏的问题

    在headless模式下,是没有打开浏览器窗口的,那么driver.maximize_window(),找不到目标也打不开. 我们可以换一种方式,去在无头模式下,指定浏览器的窗口大小运行即可. __o ...

  10. symfony4 404页面未找到

    symfony4 404页面未找到 安装好symfony4后,发现除了首页能正常显示,其他页面如/_profiler_/等其他创建的router访问都显示The requested URL /xxx ...