在面向服务开发的时代,WebApi使 .Net 的接口开发脱离IIS束缚,更加灵活,轻量,下面我们逐步实现 WebApi的多版本管控,和插件式开发
实现功能:
- 通过搭建Windows服务构造WebApi站点
- 透过 http://*/api/v1/controller 的方式访问对应版本的 API
- 插件式开发,将写好接口的dll放置在站点指定文件夹中,就可以对外提供dll中的Api
以下是逐步实现的过程
二、实现多版本管控
1.重写DefaultHttpControllerSelector类
在项目中创建一个类 VersionnControllerSelector继承DefaultHttpControllerSelector进行方法重写
直接贴代码
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
namespace WebApiService
{
public class VersionnControllerSelector : DefaultHttpControllerSelector
{
public HttpConfiguration _config;
public VersionnControllerSelector(HttpConfiguration config)
: base(config)
{
_config = config;
}
public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
Dictionary<string, HttpControllerDescriptor> dic = new Dictionary<string, HttpControllerDescriptor>();
foreach (var ams in _config.Services.GetAssembliesResolver().GetAssemblies())
{
// 获取继承自 ApiControl 的非抽象类
var controlTypes = ams.GetTypes().Where(p => !p.IsAbstract && typeof(ApiController).IsAssignableFrom(p)).ToArray();
foreach (var ctrlType in controlTypes)
{
// 从 namespace 中提取出版本号
var match = Regex.Match(ctrlType.Namespace,
@"\w+.Controller.(V\d+)", RegexOptions.IgnoreCase);
if (match.Success)
{
string verNum = match.Groups[1].Value;// 获取版本号
string ctrlName =
Regex.Match(ctrlType.Name, @"(\w+)Controller").Groups[1].Value;// 从 LoginController 中拿到 Login
string key = verNum + "/" + ctrlName;//Personv2 为 key
dic[key.ToUpper()] = new HttpControllerDescriptor(_config, ctrlName, ctrlType);
}
else
{
string ctrlName =
Regex.Match(ctrlType.Name, @"(\w+)Controller").Groups[1].Value;// 从 LoginController 中拿到 Login
string key = ctrlName;//Personv2 为 key
dic[key.ToUpper()] = new HttpControllerDescriptor(_config, ctrlName, ctrlType);
}
}
}
return dic;
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
// 获取所有 Controller 集合
var controllers = GetControllerMapping();
// 获取路由数据
var routeData = request.GetRouteData();
// 从 url 中获取到版本号
string verNum =
Regex.Match(request.RequestUri.PathAndQuery, @"api/([\w/]+)", RegexOptions.IgnoreCase).Groups[1].Value;
if (controllers.ContainsKey(verNum.ToUpper()))// 获取 HttpControllerDescriptor
{
return controllers[verNum.ToUpper()];
}
else
{
return null;
//return base.SelectController(request);
}
}
}
}
注释里边写的都挺全的
本段代码参考文章:https://www.imooc.com/article/37970
2.修改启动类
using Microsoft.Owin;
using Owin;
using System.Web.Http;
using System.Web.Http.Dispatcher;
[assembly: OwinStartup(typeof(WebApiService.Startup))]
namespace WebApiService
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//config.Services.Replace(typeof(IAssembliesResolver), new PluginsResolver());//此处是插件式开发的 配置,在此时还未实现先注释
config.Services.Replace(typeof(IHttpControllerSelector), new VersionnControllerSelector(config));//此处是多版本管控的配置,在此时还未实现先注释
app.UseWebApi(config);
}
}
}
ok,下边我们测试一下
先创建两个新版本的接口
接口代码分别为
using System.Web.Http;
namespace WebApiService.Controller.V1
{
public class GetVerController : ApiController
{
public string GetVer()
{
return "This V1 Api!";
}
}
}
和
using System.Web.Http;
namespace WebApiService.Controller.V2
{
public class GetVerController : ApiController
{
public string GetVer()
{
return "This V2 Api!";
}
}
}
我们修改一下入口代码
using System;
using Microsoft.Owin.Hosting;
using System.ServiceProcess;
namespace WebApiService
{
class Program
{
static void Main(string[] args)
{
//启动服务使用该段代码
//ServiceBase[] ServicesToRun;
//ServicesToRun = new ServiceBase[]
//{
// new WebApiService () //此处是我们的windows服务类名称
//};
//ServiceBase.Run(ServicesToRun);
//调试使用该段代码
WebApp.Start<Startup>("http://127.0.0.1:8088");
Console.WriteLine("Service Started!");
Console.Read();
}
}
}
启动项目
我们测试一下接口 http://127.0.0.1:8088/Api/GetData 返回 Hello Word!
http://127.0.0.1:8088/Api/V1/GetVer 返回 This V1 Api!
http://127.0.0.1:8088/Api/V2/GetVer 返回 This V2 Api!
好的,到现在,我们的多版本管控就完成了
下一篇,插件式开发将配合版本管控达到神奇的效果
附录
WebApi多版本管控和插件式开发(一)——WebApi服务搭建
WebApi多版本管控和插件式开发(二)——WebApi多版本管控
WebApi多版本管控和插件式开发(三)——WebApi插件式开发
附上源码:https://download.csdn.net/download/xy596356456/12864960