一.前言

第一次接触Autofac是因为CMS系统--Orchard,后来在一个开源爬虫系统--NCrawler中也碰到过,随着深入了解,我越发觉得Ioc容器是Web开发中必不可少的利器。那么,Ioc容器是用来做什么的?用了有什么好处?我相信如果不明白这两点就很难敞开心扉接受Ioc容器。

二.传统解耦设计的弊端

为方便描述,举个日志的栗子。我简化实现,一个Log类,一个SaveLog方法。如果其他类想拥有记日志功能,那么只需在内部包含一个Log类型的变量:

   public class Log
{
public void SaveLog(string message) {
// save log here.
}
} public class ProductService {
private Log _log;
public ProductService() {
_log = newLog();
} public void SaveProduct() {
// save product here.
//...
_log.SaveLog("save 1 product");
}
}

有经验的程序员可能会告诉你,这样做会导致其他类与Log耦合。于是,为了解耦,我们将Log类的功能抽象出来,ILog接口就产生了。如此一来,当其他类需要日志功能时,内含变量就从Log变成了ILog:

 public interface ILog {
void SaveLog(string message);
}
public class Log:ILog
{
public void SaveLog(string message)
{
// save log here.
}
} public class ProductService
{
private ILog _log;
public ProductService()
{
_log = newLog();
}
// .......
}

由于ILog被抽象出来,它的实现类可多样化,保存为txt、xml、数据库,甚至可扩展出邮件通知功能等。基本上,我看到的国内项目里,所谓的解耦就只能走到这一步了,但这种设计真的是所谓的“灵活,易扩展,高内聚,低耦合”吗?

现在,我们来模拟需求变更。假设已有TxtLog类把日志保存成txt文件,但使用一段时间后发现:这种日志难以查询。项目经理决定将日志保存到数据库,DbLog类应运而生。但是由于整个系统充斥着new TxtLog(),转换过程实质上就是逐个查找TxtLog替换成DbLog的过程。此时,项目大小决定出错率,出错导致日志记录不全,记录不全导致系统故障后查不到日志,查不到日志导致找不到原因,找不到原因导致加班,后果太严重了。

忽然有天,高潮降临,经理或老板决定换回txt或换另外一种日志形式,原因不明,或节省成本,或体验不好,或佞臣谗言,或成心玩你,或与数据库有世仇,总之--TMD就是要换。于是,悲剧的查找替换再次上演,几番折腾,千疮百孔。

而此时此刻,你还会称赞这种设计“灵活,易扩展”吗?

三.迈进IoC大门--改变实例化的方式

现在我们使用Ioc容器--Autofac改进上面的代码,目标是消除代码中的new语句,把实例化类的控制权转移到别的地方,这个地方通常会在一个程序加载时只执行一次的全局方法中。

 public class Global {
public static IContainer container;
public void Application_Start() {
ContainerBuilder builder=newContainerBuilder();
builder.RegisterType<Log>().As<ILog>();
builder.RegisterType<ProductService>();
container = builder.Build();
var productService = container.Resolve<ProductService>();
}
} public class ProductService
{
private ILog _log;
public ProductService(ILog log)
{
_log = log;
}
// .......
}

上面代码中,ContainerBuilder和IContainer是Autofac中的核心类(之后的文章中会介绍,本文不赘述)。当我们要实例化一个ProductService时,需要写如下代码:

 var productService = container.Resolve<ProductService>();

没有任何跟Log有关的操作,但productService中的_log变量确已被赋值了一个Log的实例。Ioc容器会在已注册的组件(类或接口)中匹配实例化参数的类型,一旦发现该类型注册过,则自动将对应的实例赋值给该类型,这个过程叫做--构造函数注入。

回头看看那个曾经折磨过我们的TxtLog换DbLog的问题,托Ioc的福,只要在那个全局方法中改一下类型就解决了。

四.Ioc不仅仅是控制翻转

也许你会说这个栗子有些极端,实际开发中查找替换的地方并不多,而Ioc只是给实例化换了个地方而已,为了这么一点收益却要付出巨大的学习成本,是否值得?

实际上,Ioc除了控制反转外,还提供了很多对实例生命周期的控制,本文使用的Autofac针对流行的框架(如MVC,WCF)提供了简易整合模块,以及动态代理功能。在不修改原代码的前提下,如何为类中方法添加逻辑?Orchard框架通过Autofac和DynamicProxy库设计出一种很有意思的架构让两个不相干的类的方法逻辑能合并在一起。更多细节,我会在之后的系列文章中向大家展示。

五.结语

5月,天降陨星,三斤大菠萝来袭,我与基友拔剑而起向邪恶宣战。如今战罢收心,准备踏实写一些文章与大家分享,希望这次能坚持久一些^_^。

******************************************************************************

转载:http://www.cnblogs.com/hkncd/archive/2012/11/21/2780041.html

Ioc容器Autofac系列(1)-- 初窥的更多相关文章

  1. Ioc容器Autofac系列(3)-- 三种注册组件的方式

    简单来说,所谓注册组件,就是注册类并映射为接口,然后根据接口获取对应类,Autofac将被注册的类称为组件. 虽然可像上篇提到的一次性注册程序集中所有类,但AutoFac使用最多的还是单个注册.这种注 ...

  2. Ioc容器Autofac系列(2)-- asp.net mvc中整合autofac

    经过上篇蜻蜓点水的介绍后,本篇通过实例快速上手autofac,展示当asp.net mvc引入了autofac之后会带来什么. 创建Asp.net MVC并引入Autofac 首先,创建一个MVC站点 ...

  3. Ioc容器Autofac系列

    1.http://blog.csdn.net/xingxing513234072/article/details/9211969 2.asp.net mvc中整合autofachttp://blog. ...

  4. [转]Ioc容器Autofac

    本文转自:http://www.cnblogs.com/hkncd/archive/2012/11/21/2780041.html Ioc容器Autofac系列(1)-- 初窥   前言 第一次接触A ...

  5. .net core2.0下Ioc容器Autofac使用

    .net core发布有一段时间了,最近两个月开始使用.net core2.0开发项目,大大小小遇到了一些问题.准备写个系列介绍一下是如何解决这些问题以及对应技术.先从IOC容器Autofac开始该系 ...

  6. IoC容器Autofac(5) - Autofac在Asp.net MVC Filter中的应用

    Autofac结合EF在MVC中的使用,上一篇IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)已经介绍了.但是只是MVC中Co ...

  7. IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)

    转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html  有修改 Autofac通过Controller默认构造 ...

  8. IoC容器Autofac学习笔记

    一.一个没有使用IoC的例子 IoC的全称是Inversion of Control,中文叫控制反转.要理解控制反转,可以看看非控制反转的一个例子. public class MPGMovieList ...

  9. IOC容器 - Autofac概述

    Autofac是比较出名的Ioc容器之一,熟悉Orchard的应该熟知.本文直接介绍autofac用法 一.开始 1.NuGet添加或者直接http://code.google.com/p/autof ...

随机推荐

  1. Testing - 测试基础 - 自动

    自动化测试模型 一个自动化测试框架就是一个集成体系,在这一体系中包含测试功能的函数库.测试数据源.测试对象识别标准,以及种可重用的模块. 自动化测试框架在发展的过程中,不断有新的模型(概念)被提出,目 ...

  2. 让 jQuery UI draggable 适配移动端

    背景: 在移动端,本人要实现对某个元素的拖动,想到使用 jQuery UI 的 draggable 功能.但是发现此插件的拖动只支持PC端,不支持移动端. 原因: 原始的 jQuery UI 里,都是 ...

  3. Flexbox制作CSS布局实现水平垂直居中

    Flexbox实现一个div元素在body页面中水平垂直居中: <!DOCTYPE html><html lang="en"><head>  & ...

  4. window、document、html、body、element的事件属性比较

    在分析jQuery的事件的时候有提到绑定事件的方式: Dean Edwards的跨浏览器事件绑定使用的方式是 element["on" + type] = handleEvent; ...

  5. linux useradd 命令基本用法

    在 Linux 中 useradd 是个很基本的命令,但是使用起来却很不直观.以至于在 Ubuntu 中居然添加了一个 adduser 命令来简化添加用户的操作.本文主要描述笔者在学习使用 usera ...

  6. Linux ACL

    ACL 是什么 ACL的全称是 Access Control List (访问控制列表) ,一个针对文件/目录的访问控制列表.它在UGO权限管理的基础上为文件系统提供一个额外的.更灵活的权限管理机制. ...

  7. Clr静态数据Table-Valued函数

    前两天Insus.NET实现一个功能<在数据库中提供只读数据>http://www.cnblogs.com/insus/p/4384411.html ,在数据库中为程序提供静态数据.它是在 ...

  8. 现在就使用HTML5的十大原因

    你难道还没有考虑使用HTML5? 当然我猜想你可能有自己的原因: 它现在还没有被广泛的支持,在IE中不好使,或者你就是喜欢写比较严格的XHTML代码. HTML5是Web开发世界的一次重大的改变,事实 ...

  9. iOS阶段学习第四天笔记(循环)

    iOS学习(C语言)知识点整理笔记 一.分支结构 1.分支结构分为单分支 即:if( ){ } ;多分支 即:if( ){ }else{ }  两种 2.单分支 if表达式成立则执行{ }里的语句:双 ...

  10. 一文读懂UGC:互联网上的生态秘密

    转载自近乎: UGC(User- Generated Content)用户原创生产内容,它是相对于PGC(Professionally-produced Content)专业生产内容的一种内容来源,简 ...