一.前言

第一次接触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;
}
// .......
}

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

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

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

回头看看那个曾经折磨过我们的TxtLogDbLog的问题,托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. 精致3D图片切换效果,最适合企业产品展示

    这是一个精致的立体图片切换效果,特别适合企业产品展示,可立即用于实际项目中.支持导航和自动播放功能, 基于 CSS3 实现,推荐使用最新的 Chrome,Firefox 和 Safari 浏览器浏览效 ...

  2. 使用 CSS3 实现 3D 图片滑块效果【附源码下载】

    使用 CSS3 的3D变换特性,我们可以通过让元素在三维空间中变换来实现一些新奇的效果. 这篇文章分享的这款 jQuery 立体图片滑块插件,利用了 3D transforms(变换)属性来实现多种不 ...

  3. 15 Best Responsive HTML5 Frameworks 2014

    Best HTML5 frameworks are most popular because with the use of these frameworks you can create websi ...

  4. WPF依赖属性详解

    WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...

  5. 转 Windows+VS2013爆详细Caffe编译安装教程

    1. 安装cuda Cuda是英伟达推出的GPU加速运算平台 我这里安装的是cuda7.5,已经安装过的忽略,还没有安装过的这里有安装教程.windows下面安装还是非常简单的. 点击打开链接    ...

  6. 两种读写配置文件的方案(app.config与web.config通用)

    第一种方法:采用MS现有的ConfigurationManager来进行读写 using System.Configuration; namespace Zwj.TEMS.Common { publi ...

  7. 理解SQL Server是如何执行查询的 (2/3)

    查询执行的内存授予(Query Execution Memory Grant) 有些操作符需要较多的内存才能完成操作.例如,SORT.HASH.HAS聚合等.执行计划通过操作符需要处理数据量的预估值( ...

  8. 瀑布式开发、迭代开发、敏捷开发、XP与SCRUM的区别

    瀑布式开发.迭代开发,区别[都属于,生命周期模型]         两者都是一种开发模式,就像设计模式一样,考虑的角度不一样,个人感觉谈不到取代一说.         传统的瀑布式开发,也就是从需求到 ...

  9. MySqlHelper、CacheHelper

    MySqlHelper代码: using System; using System.Collections; using System.Collections.Generic; using Syste ...

  10. HTTP & HTTPs

    HTTP HTTP 消息 HTTP 方法 参考 [1]. HTTP 协议初识 - 阮一峰: HTTPS 参考 [1]. HTTPS 升级指南 - 阮一峰: