在之前的一些博客文章中,我曾多次提到过 NancyFx (简称: Nancy) 这个框架。技术这东西就应该与时俱进、常用常新!做了这么多年的 ASP.NET 和 ASP.NET MVC 应用开发,换换思路用用新东西也是不错的。最近比较密集的在几个项目中深度使用了 Nancy,甚至对一个前后端业务逻辑都很复杂的原 ASP.NET MVC 项目,用 Nancy 框架完全重写 —— 2 个人用时不到两周。我们在 .NET 方向上彻底爱上了 Nancy,从本篇开始我将为大家逐步介绍 Nancy 这个优秀的轻量级开源 Web 框架。
为什么选择Nancy
ASP.NET MVC 是微软基于 ASP.NET 开发的类 ROR (Ruby On Rails) 的 Web 框架,相比 ASP.NET WebForm 来说更适合团队协作开发面向互联网的 Web 应用。由于更加接近原始的 Web 应用形态,所以灵活性比 ASP.NET WebForm 更高,深受 .NET Web Application 开发者们的喜爱。
但是经过了 5 个大版本的迭代之后,ASP.NET MVC 依然没有脱离 ASP.NET 这个笨重的老家伙。当你想绕过 ASP.NET 做一些事情时,会发现那是不可能的;当你需要一种洁净的灵活的 URL 时,你会发现 ASP.NET MVC 需要你设置甚是复杂的路由才能满足;当你想把单元测试进行的更加深入时,你会发现很难很难——笨重的 Context 天生无法灵活的 Mock!—嗯,你可能会说,微软的 Fakes 不错对 Mock Context 还是有帮助的。但请注意,我前面说的是难而不是不能哦,不管你用 Moq 还是 Fakes,都挺难,因为设计的时候就没怎么考虑这个事情。
所以,我们需要一种新的选择,至少应该是另外一可选项。Nancy 就是选项之一,而且表现还不错。
下面来罗列一下 Nancy 的几个特点吧
- 开源&社区化
- 不依赖于 ASP.NET
- MVC 模式不是必选项
- 先天易于测试
- 先天支持依赖注入
- 高度可定制
- 简洁明快
- 跨平台 (支持 .NET 和 Mono)
- 支持内容协商
- 可以 host 在任何应用中
- ……
开源&社区化
Nancy 是完全开源的框架,MIT 协议,源代码 Host 在的 GitHub上。Nancy 框架相关的项目都在 https://github.com/NancyFx 上。其中核心项目 https://github.com/NancyFx/Nancy 的 Star 已经接近 3000,nuget 上的 package 下载总量已经超过 20 万。nuget 上与 Nancy 有关的 package 超过 120 个。
Nancy 的官方博客 http://blog.nancyfx.org 里,时不常的会写一些不错的相关内容。
Nancy 官方还开设了一个 MVM (Nancy Most Valued Minion Award) 奖项,很类似于微软的 MVP 奖项。目前还没有什么很值钱的奖励,但可以被授权使用该奖项的徽章,放在自己的博客网站上。
Christian Horsdal 在 2013 年出版过一本 74 页的 Nancy 书《Instant Nancy Web Development》,大部分内容目前仍然不过时,只是价格对中国人来说有点贵 - $12.99。
不依赖于ASP.NET
System.Web 是 ASP.NET 的核心 dll。它包含了整个 Web 应用所需的各种类型,不管你用多少,它就在那里,不少不轻~
Nancy 是通过插件机制来提供额外功能或替代功能的。Nancy 不绑定任何特定的实现或框架,所有的请求和响应处理都构建在松散耦合和自由定制的基础理念上的。这意味着,Nancy 可以运行在 .NET Client Profile 环境下,而不必像 ASP.NET MVC 那样要求必须安装 .NET 完整框架。它不依赖于 ASP.NET 框架也就是 System.Web.dll,也就不必受 ASP.NET 的约束。
MVC模式不是必选项
Nancy 不强迫你坚持使用 Model-View-Controller 的 MVC 模式或其他任何模式,只是一种响应 http 请求的服务端框架,适合用于构架网站、WebService 或者 WebAPI 等类型的应用。
这并不意味着你就不能在 Nancy 上使用 MVC 模式,你可以在 Views 文件夹下定义自己的视图,创建 Models 返回到端点上或者映射请求到 Models 上,就如同你使用 ASP.NET MVC 一样。所以如果你熟悉 ASP.NET MVC 那么你很容易上手使用 Nancy,不必担心学习成本问题。
先天易于测试
Nancy 提供了一个可以完整测试 requst/response 周期的类库,这样你不仅可以测试你的请求返回 Model 是否符合期望,也可以通过 accept 标头测试响应的格式是否正确。 Nancy 可以在没有 Server 的情况下就能测试请求响应,而在 ASP.NET MVC 中很难。
先天支持依赖注入
Nancy 中集成了一个叫做 TinyIoC 的组件,可以自动发现你所有的依赖关系,也可以在应用中设置一些特定的依赖关系——在 Bootstrapper 类中通过各种方法或属性可以配置 Nancy 应用。
当然了,你也可以使用插件机制将 TinyIoC 的 Container 更换为 Autofac、Unity、Windsor、StructureMap、Ninject …… 之类的,具体用哪个就看自己需求和喜好了。
高度可定制
Nancy 的核心特征之一就是可扩展性。它被设计为允许你替换任何你想要替换的部分:你可以自定义 Model 绑定程序、视图渲染器、序列化程序等。事实上你可以实现自己的 INancyEngine,甚至彻底改变 Nancy 的请求处理逻辑等等。Nancy 自带了一组预定义的约定,如果你希望 Nancy 换个约定规则,你可以替换它。所有的一切都是可以定制的,具备极大的可扩展性。
简洁明快
Nancy 的另一个核心理念就是让 Web 开发变得简单快捷。通过简洁的语法规范,可以让你在不影响应用程序的前提下,代码更整洁易懂。可以用很少量的代码就能开发一个轻量级应用。
跨平台
Nancy 并没有将自己依赖于某个操作系统平台下,它可以运行在 Windows 的 .NET 上,也通过 Mono 非常好的运行在 Mac OSX 和 linux 系统上。Nancy 也可以运行在树莓派 (Raspberry Pi) 这类 Mini PC 平台上 —— 当然了,ASP.NET MVC 也多数情况下可以运行在多种平台下,尤其是 ASP.NET MVC 6 这个全新的版本。
支持内容协商
类似于下面的代码,在 Nancy 中运行出来的结果并非一成不变的。
Get["/"] = p => {
var model = SomeModel();
return model;
};
它可以通过内容协商 (Content Negotiation) 机制,通过 accept 的 Header 值来决定使用何种方式渲染最终的结果。
默认情况下,如果用户使用浏览器访问应用程序的 “/” 路径,Nancy 会查找一个名字是 model 对应类型名的视图,并将 model 的数据传递给视图,调用相应的视图引擎渲染后,响应给用户一个页面;
而如果客户端使用 ajax 之类的方法,告诉服务端你要获取的是 json 或 xml 格式数据,那么上面的代码返回的就不是一个网页,而是 model 做相应序列化后的数据。
这样你的一段代码、同一个地址可以用来提供多种服务。是不是很酷呢?
可以host在任何应用中
Nancy 算是一个主机不依赖主义者,可以运行在 IIS、WCF、ASP.NET、嵌入在 exe 中作为 windows 服务或 selfhost 应用跑。当然也可以通过 fastcgi-mono-server,运行在 nginx、Apache、Lighttpd 之类的 Linux 常用 WebServer 上。值得一提的是国产免费 webserver —— Jexus 可以更方便高效的运行 Nancy,本博客就是运行在 Jexus 上,安装方式可以参考我之前的文章《Ubuntu Server 上安装 Jexus》。总之,它几乎可以无处不在的!
Hello world
大多数程序猿/媴们写的第一个应用就是 Hello world,这已经算是这行的惯例了。下面的代码跑起来后,浏览器浏览应用的 "/" 地址,就会看到伟大的 “Hello world”。
public class HomeModule : Nancy.NancyModule
{
public HomeModule()
{
Get["/"] = x => "Hello World!";
}
}
怎么样,够简洁明快了吧!Nancy 默认有两个约定的地方:
- 每个模块都要派生自 NancyModule,NancyModule 类似于 MVC 中的 Controller
- 构造函数中定义路由地址和请求方式,
Get["/"]
表示通过 GET 方式请求 "/" 地址。
好,更细节的内容,我将从下一篇开始带大家一起详细了解。