NancyFX 第十一章 Bootstrapping
本章我们将深入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的更多相关文章
- CPrimerPlus第十一章中的“选择排序算法”学习
C Primer Plus第十一章字符串排序程序11.25中,涉及到“选择排序算法”,这也是找工作笔试或面试可能会遇到的题目,下面谈谈自己的理解. 举个例子:对数组num[5]={3,5,2,1,4} ...
- <构建之法>第十一章、十二章有感
十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)
第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的 DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...
- 第十一章 TClientDataSet
第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...
- 第十一章、认识与学习BASH
第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...
- [Effective Java]第十一章 序列化
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- EFFECTIVE JAVA 第十一章 系列化
EFFECTIVE JAVA 第十一章 系列化(将一个对象编码成一个字节流) 74.谨慎地实现Serializable接口 *实现Serializable接口付出的代价就是大大降低了“改变这个类 ...
- 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高
第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...
- [CSAPP笔记][第十一章网络编程]
第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真 ...
随机推荐
- Android查缺补漏(IPC篇)-- 款进程通讯之AIDL详解
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- iOS视频直播
视频直播技术点 视频直播,可以分为 采集,前处理,编码,传输, 服务器处理,解码,渲染 采集: iOS系统因为软硬件种类不多, 硬件适配性比较好, 所以比较简单. 而Android端市面上机型众多, ...
- PHP操作Redis队列的方法
入队: <?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); while(True){ try{ $value = ...
- 1.8 range
哈哈,前边忘了介绍这个知识点了,老是用人家,不介绍一下都不好意思了. range()函数是一个用来创建数字序列的函数. 问题来了,为什么要写函数? 封装代码啊,让使用者不需要关心具体业务逻辑是如何实现 ...
- svn版本管理系统出现的问题解决办法
首先会出现下面的一个提示错误: cannot checkout from svn run 'cleanup' if it was interrupted 百度加谷歌找到的解决问题的办法各种各样,自己遇 ...
- Mapreuduce实现网络数据包的清洗工作
处理后的数据可直接放到hive或者mapreduce程序来统计网络数据流的信息,比如当前实现的是比较简单的http的Get请求的统计 第一个mapreduce:将时间.十六进制包头信息提取出来,并放在 ...
- Android 热补丁实践之路
最新github上开源了很多热补丁动态修复框架,主要的大致有: https://github.com/dodola/HotFix https://github.com/jasonross/Nuwa h ...
- redis的密码设置(windows与linux相同)
接着我们昨天的说,昨天redis的启动已经了解,今天来说说redis的密码设置.(不管怎么说redis也是数据库,也需要密码) 修改密码可以2种行径.第一种,直接修改配置文件,打开redis.conf ...
- Hi3531 SDK v2.0.8.0 安装
1.Hi3531 SDK包位置 在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx.x.x.x.tgz ...
- 【javascript】jQuery判断用户右击事件
jquery 判断用户是鼠标是右击还是左击, // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键 $(document).mousedown(function(e) { if(3 ...