第一次看到TinyIoCContainer是在用NancyFx的时候,在Bootstrapper那里看到了她的影子。

那些叫Tiny的东西都挺有意思,IoC容器是我第一次遇到,于是找了些文章看了看,自己写了点代码实践下,这件事就算这么过了,然后今天想起来,在做下笔记。

首先是DIP的概念:依赖倒置原则,OOD的产物。

那么IoC就是DIP的实现方式,用我粗糙的话来说就是类依赖抽象就不在类内部自己new,交给别人new好了再用。

来一个应用场景:

  玩家玩游戏机。

代码差不多这样:

     interface IGameMachine
{
void Launch();
} class Player
{
public IGameMachine GameMachine; public void Play()
{
       if(GameMachine!=null)
   GameMachine.Launch();
}
} class PS3 : IGameMachine
{
public void Launch()
{
Console.WriteLine("索尼大法好,PS3开起来啦!");
}
}

这里定义了一个Player类表示玩家,玩家玩的是游戏机,并不指定是什么游戏机,所以有个可以“跑”的游戏机接口,PS3实现了这个接口。那么我就可以在通过赋值更换玩家手上的游戏机来玩PS3了。

1  Player player = new Player();
2  player.GameMachine = new PS3();
3  player.Play();

这样就实现了上面说的“不在类内部new,交给别人new”这一点。

交给TinyIoCContainer来完成就是这样:

1  TinyIoCContainer tiny = new TinyIoCContainer();
2  tiny.Register<IGameMachine, PS3>();
  Player player = new Player
4  {
5    GameMachine = tiny.Resolve<IGameMachine>()
  };
7  player.Play();

大多数情况下,在项目中遇到的还没这种可能随时更换的,而是一旦启动就不更换的组件,像数据库之类的,这样的情况下,这个接口成员就可以不public出来,而是private并且通过构造函数初始化。

还是同样的应用场景,只是玩家都变得很穷很穷了,一辈子就只能买一台游戏机。改造下Player类之后,我们可以这样使用TinyIoCContainer了:

    class Player
{
private readonly IGameMachine _gameMachine; public Player(IGameMachine gameMachine)
{
_gameMachine = gameMachine;
} public void Play()
{
if (_gameMachine != null)
_gameMachine.Launch();
else
Console.WriteLine("没初始化");
}
} static void Main(string[] args)
{
TinyIoCContainer tiny = new TinyIoCContainer();
tiny.Register<IGameMachine, PS3>();
Player player = tiny.Resolve<Player>();
player.Play();
Console.ReadLine();
}

哈,这里只是注册了IGameMachine对应PS3,也可以Resolve出Player来,并且通过构造函数创建了PS3呢。

于是,再进一步想一下,假如GameMachine也有依赖的抽象需要实现呢?

那么应用场景再进一步调整:

玩家有一台游戏机,游戏机可以插各种游戏卡带

那么游戏机就有了一个属性游戏卡带,我也希望游戏卡带能通过构造函数初始化。上面说过的DIP的概念只是说依赖抽象,所以,游戏机从接口抽象改成了抽象类。

     class GameBoy : GameMachine
{
protected override void OnPlay()
{
Console.WriteLine("我是任饭,我玩GameBoy!");
} public GameBoy(GameCard currentCard) : base(currentCard)
{ }
} abstract class GameMachine
{
private GameCard _currentCard; protected GameMachine(GameCard currentCard)
{
_currentCard = currentCard;
} public void Launch()
{
OnPlay();
Console.WriteLine("我在玩{0}", _currentCard.Name);
} protected abstract void OnPlay();
} public abstract class GameCard
{
public abstract string Name { get; }
} public class PoketMonster:GameCard
{
public override string Name
{
get { return "口袋蓝"; }
}
}

稍微更改下Player类,替换接口IGameMachine成抽象类GameMachine。

那么使用的时候,我们在容器中注册GameCard为PoketMonster,GameMachine为GameBoy试试看。

     static void Main(string[] args)
{
TinyIoCContainer tiny = new TinyIoCContainer();
tiny.Register<GameMachine, GameBoy>();
tiny.Register<GameCard, 口袋妖怪>(); Player p = tiny.Resolve<Player>();
p.Play(); Console.ReadLine();
}

运行输出

初试TinyIoCContainer笔记的更多相关文章

  1. 学习笔记之 初试Caffe,Matlab接口提取feature

    Caffe 提供了matlab接口,可以用于提取图像的feature.

  2. 学习笔记之 初试Linux遇到的问题 2015-10-13

    1. 安装.deb文件,用sudo gdebi XXX.deb sudo apt-get install xxx 2. 需要配置系统路径: LD_LIBRARY_PATH=.../lib:LD_LIB ...

  3. NLP自然语言处理学习笔记二(初试)

    前言: 用Python对自然语言处理有很好的库.它叫NLTK.下面就是对NLTK的第一尝试. 安装: 1.安装Pip 比较简单,得益于CentOS7自带的easy_install.执行一行命令就可以搞 ...

  4. Asp.net SignalR 初试和应用笔记一 认识和使用 SignalR

    如果你在用QQ,微信.你会知道,广告和消息无处不在.也有好的一面,比如通过QQ或微信,微博等及时聊天功能,你找到了你的初恋,你找到了小学的班级等等. 这里的及时通信在很多应用场所能用到,比如: 1.球 ...

  5. [ajax 学习笔记] ajax初试

    ajax全称是:asynchronous javasctipt and xml. 1.为什么须要ajax? 一般web程序与server的交互是:页面发送请求等待server处理,server处理数据 ...

  6. 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  7. Mysql学习笔记(二)对表结构的增删改查

    有将近一个星期都没有更新mysql了.相反linux的东西倒是学习不少.可能我个人情感上对linux更感兴趣一点.但mysql我也不烦,只是一旦将精力投入到了一样事情上去,就很难将精力分散去搞其他的东 ...

  8. [自娱自乐] 3、超声波测距模块DIY笔记(三)

    前言 上一节我们已经研究了超声波接收模块并自己设计了一个超声波接收模块,在此基础上又尝试用单片机加反相器构成生成40KHz的超声波发射电路,可是发现采用这种设计的发射电路存在严重的发射功率太低问题,对 ...

  9. 小猪猪C++笔记基础篇(五)表达式、语句

    小猪猪C++笔记基础篇(五) 关键词:表达式.语句 本章的内容比较简单,基本上没有什么理解上的困难,都是知识上的问题.先开始想要不要写呢,本来是不准备写的,但是既然读了书就要做笔记,还是写一写,毕竟还 ...

随机推荐

  1. MVC 构建图片/文件选择器 参考其它CMS功能

    实现结果,如下 点击选择图片,弹出一个iframe框 顶部默认图片根目录,依次下面是文件列表 底部是选择的文件地址,以及上传新的图片和文件 加载iframe 调用js方法 function initF ...

  2. ubuntu locale 语言设置

    第一步,编辑文件 代码: sudo gedit  /var/lib/locales/supported.d/local 写入相关内容,比如写入如下内容: 代码: zh_CN.UTF-8 UTF-8zh ...

  3. Regular Expression Matching leetcode

    递归方法运行时间过长.考虑使用动态规划的方法. 代码如下: bool isMatch(string s, string p) { int i,j; int m=s.size(); int n=p.si ...

  4. Zabbix(一)--zabbix 2.4.8 安装

    zabbix依赖于LAMP,所以部署前要先保证这个平台. 安装服务端(Server) zabbix官网的rpm包都是按照功能分开一个个,比如: zabbix-server-2.4.7-1.el7.x8 ...

  5. My安卓知识2--使用listview绑定sqlite中的数据

    我想在我的安卓项目中实现一个这样的功能,读取sqlite数据库中的数据并显示到某个页面的listview控件中. 首先,我建立了一个Service类,来实现对数据库的各种操作,然后在这个类中添加对数据 ...

  6. 《Objective-C编程》部分示例

    <Objective-C编程>部分示例 最近在看<Objective-C编程>顺带实现了书中部分示例代码.如果感兴趣可以自行 下载(点我). 通过本书大致了解了Objectiv ...

  7. Ceph剖析:消息处理

    作者:吴香伟 发表于 2014/10/9 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 总体上,Ceph的消息处理框架是发布者订阅者的设计结构.Messenge ...

  8. git conifg

    1. git config简介 我们知道config是配置的意思,那么git config命令就是对git进行一些配置.而配置一般都是写在配置文件里面,那么git的配置文件在哪里呢?互动一下,先问下大 ...

  9. React阶段开发总结

    这次独立编写了React页面主要是数据切换.点击不同的按钮,Ajax请求不同的后台数据.数据驱动表格内容的显示.使用React组件开发. 开发中获得下面的心得: 1.后台给的地址早一点添加路由(写好数 ...

  10. Linux下chkconfig命令详解

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...