转载

Nancy 详解(一) 初识

Nancy 是一个轻量级的,简单粗暴的framework用来构建基于HTTP的各种服务,兼容.Net和Mono。Nancy的整套设计理念是基于"super-duper-happy-path",这是一个作者杜撰的单词,个人觉得翻译过来基本就是简单粗暴,行之有效的意思。

简单的例子:

public class Module : NancyModule {     public Module()     {         Get["/greet/{name}"] = x => {             return string.Concat("Hello ", x.name);         };     } }

github上的例子后面跟着的是 Compile, run and enjoy the simple, elegant design! ,这句话让我深深的感受到这群程序员的可爱。

Features

  1. 自底向上全套都是新构建的,移除了对其他框架的引用和限制。
  2. Run anywhere. Nancy 能够在ASP.NET/IIS,OWIN,Self-hosting中运行。
  3. 集成支持各种View engine(Razor, Spark, dotLiquid, SuperSimpleViewEngine...)
  4. 一个强力而且轻量级的测试框架。
  5. 内容协商。
  6. And much, much more

如果本文就这样结束了,那和其他介绍的文字就没有多大的区别了。让我们坐上github的时光机,开始我们的扒皮之旅。

第一站:version-20101128

Nancy 详解(一) 初识

这个时候的Nancy 就如同一个刚出生的婴儿,也正因为如此,才便于我们入手。入口点当然是大家耳熟能详的 IHttpHandler 。这里的 IsReusable 可是false的,有一定的性能损失,这里的知识点大家可以参见另外的博文。

public class NancyHttpRequestHandler : IHttpHandler {  public bool IsReusable  {   get { return false; }  }  public void ProcessRequest(HttpContext context)  {   //...  } } 

既然刚出生,自然问题很多,就如同下面的代码,这里本着不吐槽的原则,只是笑而不语,恩恩。

public void ProcessRequest(HttpContext context) {  var url = context.Request.Url.AbsolutePath;  if (url.Contains("favicon.ico"))  {   return;  }  var request = CreateNancyRequest(context);  var assembly =    context.ApplicationInstance.GetType().BaseType.Assembly;  var engine =   new NancyEngine(new NancyModuleLocator(assembly), new RouteResolver());  var response = engine.HandleRequest(request);  SetNancyResponseToHttpResponse(context, response); } 

值得赞赏的是单元测试一开始就跟上了项目进度,这样方便我们去研究其代码的意图。其中比较有意思的是Response类的实现,里面使用了隐式的类型转换,用来实现无论是HttpStatusCode还是Content都直接用 = 赋值即可,当然这么做会带来一定的副作用。

 public void Should_set_status_code_when_implicitly_cast_from_int() {  // Given, When  Response response = 200;  // Then  response.StatusCode.ShouldEqual(HttpStatusCode.OK); } public void Should_set_status_code_when_implicitly_cast_from_http_status_code() {  // Given, When  Response response = HttpStatusCode.NotFound;  // Then  response.StatusCode.ShouldEqual(HttpStatusCode.NotFound); } public void Should_return_contents_when_implicitly_cast_to_string() {  // Given  const string value = "test value";  Response response = value;  // When  String output = response;  // Then  output.ShouldEqual(value); } 

具体的隐式转换倒是没啥内容。

public static implicit operator Response(HttpStatusCode statusCode) {  return new Response { StatusCode = statusCode }; } public static implicit operator Response(int statusCode) {  return new Response { StatusCode = (HttpStatusCode)statusCode }; } public static implicit operator Response(string contents) {  return new Response { Contents = contents, ContentType = "text/html", StatusCode = HttpStatusCode.OK }; } public static implicit operator string(Response response) {  return response.Contents; } 

Request

对于Request 的包装暂时只是占了个坑,后续版本有补充cookie的一些操作在这里。

public interface IRequest {  string Path { get; }  string Verb { get; } } public class Request : IRequest {  public Request(string verb, string path)  {   this.Path = path;   this.Verb = verb;  }  public string Path { get; private set; }  public string Verb { get; private set; } } 

つづく

正文到此结束
Loading...