本章我们将深入Nancy的内部,对Nancy的内部组件进行修改和调整。

那什么是bootstrap哪?字典里是这么介绍的:

一般而言,处于引导中(bootstrapping)是在终端用户可以使用之前开启软件或硬件的一种状态。    对于Nancy而言,引导过程(bootstrap)是应用程序刚刚开始启动到准备好应对服务请求这个过程中的发生的一连串事件。

一个自定义引导程序bootstrapper是开发人员自己定义的一个类,可以在应用开启时由Nancy的内核处理程序执行一些自定义选项或是过程。

这就好比好比买了辆二手汽车,然后调整发动机增加更多性能,添加一些内饰和新的收音机,根据自己的风格改进一些其他什么的。通过编写和使用自定义引导程序,就能给Nancy增加很多开箱即用的额外功能。

Nancy中采用引导程序(bootstrapper)主要有两方面的用途。首先是以方法的形式展现 钩子程序,配置选项以及其他用户级别的东西,开发人员可进行重载。其次是处理一些特定的任务,比如配置内置的Ioc容器(控制反转):TinyIOC ,提供对自己程序集的注册。

 Ioc容器

在我们继续探索前,我想先介绍下Nancy的隐含特征:内置Ioc容器。

对于那些还不了解Ioc的读者先简单介绍下概念。IoC(Inversion of Control​,控制反转)也称为依赖注入(Dependency Injection),是一种设计对象之间依赖关系的原则及其相关技术。当一个对象创建时,它所依赖的对象由外部传递给它,而非自己去创建所依赖的对象(比如通过new操作)。因此,也可以说在对象如何获取它的依赖对象这件事情上,控制权反转了。这种技术无外乎都是为了让软件更加高内聚低耦合。

对于基于Nancy的应用,Ioc容器也是用于自动装载依赖项。试看下面的路由模块:

using System;
using System.Collections.Generic;
using System.IO;
using Nancy;
using Nancy.Responses;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
private FakeDatabase _db;
public BaseRoutes()
{
Get[@"/"] = _ =>
{
var _db = new FakeDatabase();
var myList = db.GetHashCode();
return View["myview", myList];
};
}
}
}

这个例子很简单,但很有说明意义。

在这个模块中,FakeDatabase 是一个具体的依赖类(被引用的类)。这个比较难以管理,非常难以改变。试想你有20个这样的模块类,每个都定义了10条左右的URL,每个URL路由中都引用同样的数据访问库,每次使用时都需要创建一个新的实例。

假如你现在需要把FakeDatabase 修改为RealDatabase。然后你会突然意识这会涉及到多少工作量。

使用Ioc容器在这方面就能提升很多。如下:

using System;
using System.Collections.Generic;
using System.IO;
using Nancy;
using Nancy.Responses;
namespace nancybook.modules
{
public class BaseRoutes : NancyModule
{
private readonly FakeDatabase _db;
public BaseRoutes(FakeDatabase db)
{
_db = db;
Get[@"/"] = _ =>
{
var myList = _db.GetHashCode();
return View["myview", myList];
};
}
}
}

  

这个例子和之前的差不多,只是使用了Ioc容器来管理数据访问库。一个路由模块即使使用10次数据访问类,也只需要修改两个地方:一个是私有变量,另外是构造函数的参数。

Ioc容器会处理其他部分,包括在使用数据库访问类前,就给_db 装载正确的引用实例。

还有更好处理办法, 在Nancy的 bootstrapper类中,通过重载Ioc容器的默认设置,告诉Nancy在需要使用FakeDatabase对象时,使用RealDatabase对象进行替换。这样仅仅通过一个全局类中的修改,节省了每个路由模块中的两处修改。

Nancy可以使用很多种的Ioc容器,你可以通过NuGet来进行启用。如果你从来还接触过Ioc容器,也喜欢这种工作方式的话,内置的Ioc容器已经足够。

让我们把关注拉回到Bootstrapper类吧。

默认bootstrapper

关于重载和自定义类的讨论可能让你觉得实现这么一个Nancy bootstrapper需要大量的工作,也许是不值得的。

当然如果让你从零开始写这么一个类确实如此。然而Nancy的开发团队已经想到前头,为你提供了一个叫做DefaultNancyBootStrapper的类。

你得到一个自定义bootstrap类只需要简单继承下即可:

using System.Text;
using Nancy;
using Nancy.Bootstrapper;
namespace nancybook
{
public class CustomBootstrapper : DefaultNancyBootstrapper
{
}
}

在类主体中,你可以通过重载方法来加载自定义的功能实现方法。举个例子,你有一些外部数据库问代码库,其中使用到了泛型编程(方便共用相同的方法)。采用接口形式来定义基类,在不同的子类中实现具体功能,然后告诉Ioc容器去装载:

using System.Text;
using demodata;
using demodata.entities;
using Nancy;
using Nancy.Authentication.Forms;
using Nancy.Bootstrapper;
using Nancy.Conventions;
using Nancy.Session;
using Nancy.TinyIoc; namespace nancybook
{
public class CustomBootstrapper : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer
container)
{
base.ConfigureApplicationContainer(container);
container.Register<IDataProvider<Genre>>(new GenreDataProvider());
container.Register<IDataProvider<Album>>(new AlbumDataProvider());
container.Register<IDataProvider<Track>>(new TrackDataProvider());
container.Register<IDataProvider<Artist>>(new ArtistDataProvider());
}
}
}

在实际中,还会使用到很多的重载方法。比如在方法 RequestStartup 中配置表单验证,ConfigureRequestContainer 中配置自定义 IUserMapper ,ConfigureApplicationContainer 中注册外部的Ioc依赖项,ConfigureConventions 中设置网站应用中的静态文件夹,ApplicationStartup中处理异常。

一个自定义bootstrapper 示例

总结

NancyFX 第十一章 Bootstrapping的更多相关文章

  1. CPrimerPlus第十一章中的“选择排序算法”学习

    C Primer Plus第十一章字符串排序程序11.25中,涉及到“选择排序算法”,这也是找工作笔试或面试可能会遇到的题目,下面谈谈自己的理解. 举个例子:对数组num[5]={3,5,2,1,4} ...

  2. <构建之法>第十一章、十二章有感

    十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...

  3. sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)

    第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...

  4. 第十一章 TClientDataSet

    第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...

  5. 第十一章、认识与学习BASH

    第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...

  6. [Effective Java]第十一章 序列化

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. EFFECTIVE JAVA 第十一章 系列化

    EFFECTIVE  JAVA  第十一章  系列化(将一个对象编码成一个字节流) 74.谨慎地实现Serializable接口 *实现Serializable接口付出的代价就是大大降低了“改变这个类 ...

  8. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高

    第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...

  9. [CSAPP笔记][第十一章网络编程]

    第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真 ...

随机推荐

  1. linux 下安装php curl扩展

    方法一 安装cURL wget https://curl.haxx.se/download/curl-7.53.1.tar.gz tar -zxf curl-7.17.1.tar.gz ./confi ...

  2. MySQL数据库基础(三)(操作数据表中的记录)

    1.插入记录INSERT 命令:,expr:表达式 注意:如果给主键(自动编号的字段)赋值的话,可以赋值'NULL'或'DEFAULT',主键的值仍会遵守默认的规则:如果省略列名的话,所有的字段必须一 ...

  3. 想想我们能拿HoloLens 做点什么

    作为一个微软员工,顿时感觉好了很多. 中午吃饭同事们热烈讨论这东东: 1. 看电视 2. 办公 3. 用HoloLens 玩3d 游戏.满公园跑. 4. 看书 5. 开车的时候,实时显示地图 6. 一 ...

  4. C语言_来了解一下GCC编译器编译C可执行脚本的过程

    GCC简介    Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大.性能优越的多平台编译器,是GNU的代表作品之一.gcc是可以在多种硬体平台上编译出可执行程序的超级编译 ...

  5. 关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思

    关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思 一.遇到的问题      如题目所说,在windows的虚拟机中和windo ...

  6. PAT All Roads Lead to Rome 单源最短路

    思路:单源最短路末班就好了,字符串映射成数字处理. AC代码 //#define LOCAL #include <stdio.h> #include <string.h> #i ...

  7. 运行web项目端口占用问题

    ---恢复内容开始--- 有时候运行web项目会提示8080端口已经被占用这一类问题(Error running Tomcat8: Address localhost:1099 is already ...

  8. JavaScript的预编译和执行

    JavaScript引擎,不是逐条解释执行javascript代码,而是按照代码块一段段解释执行.所谓代码块就是使用<script>标签分隔的代码段. 整个代码块共有两个阶段,预编译阶段和 ...

  9. mysql 查询表死锁 和结束死锁的表步骤

    1.查询是否锁表 show OPEN TABLES ; 2.查询进程 show processlist 查询到相对应的进程===然后 kill    id 3.查看正在锁的事务 SELECT * FR ...

  10. PHP 常量dirname(__file__)

    PHP 常量dirname(__FILE__)取得当前文件的绝对路径. define('ROOT_PATH', str_replace('includes/2.php', '', str_replac ...