上一篇博客中,讲到了将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. ie 8及以下 前端cors ajax跨域须知

    http://www.cnblogs.com/xishuai/p/jquery-ajax-ie8-cors.html

  2. java使用memcached1--安装与基本使用

    环境 CentOs6.4 libevent-2.0.22-stable memcached-1.4.24 一.memcached安装 # cd /usr/local 1.编译安装libevent # ...

  3. wireshark 1.10.0 编译 及 协议解析部分的一些变化

    wireshark不久前升级到1.10.0稳定版,这个版本正如其版本号一样,相比1.8.x有较大变化. 我们先说说在windows下编译的问题,1.8.4/1.8.6版本的编译见我的文章:http:/ ...

  4. jquery插件制作,下拉菜单

    要求输入框点击出现下拉菜单,并实现以下功能: 1.首先点击地点标签页,选择好地点: 2.自动显示相应节点标签页显示节点信息,选择好节点 3.自动显示相应的连接点,选择连接点,连接点被选中并被传送的输入 ...

  5. django在model中添加字段报错

    在以下类中添加 description 字段后, class Colors(models.Model): colors = models.CharField(u'颜色', max_length=10) ...

  6. Thread.Sleep(1000) 、Task.Delay(1000).Wait() 区别

    public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken){    if (millise ...

  7. Codeforces Round #555 (Div. 3) A B C1(很水的题目)

    A. Reachable Numbers 题意:设f(x)为 x+1 这个数去掉后缀0的数,现在给出n,问经过无数次这种变换后,最多能得到多少个不同的数. 代码 #include<cstdio& ...

  8. mongoengine在python中的使用

    # /usr/bin/python # encoding: utf-8 # Author: masako from mongoengine import * host ='127.0.0.1' por ...

  9. 不依赖JQuery的入门Ajax代码

    今天看了head first ajax这本书里ajax的实例,讲的很好,这本书觉着很不错,推荐下. Ajax (Asynchronous Javascript and XML)即异步Javascrip ...

  10. 完美原创:centos7.1 从源码升级安装Python3.5.2

    (原创)完美原创:centos7.1 从源码升级安装Python3.5.2 下载Python3.5.2源码:https://www.python.org/downloads/release/pytho ...