回顾之前的代码

//这个类的作用是筛选出MPG类型的电影
public class MPGMovieLister
{
public Movie[] GetMPG()
{
var finder = MovieFinderFactory.GetFinder();//这里调用工厂类获取具体的实例,得到一个电影列表
var allMovies = finder.FindAll();
return allMovies.Where(m => m.Name.EndsWith(".MPG")).ToArray();
}
} public class MovieFinderFactory
{
public static IMovieFinder GetFinder()
{
return new ListMovieFinder();
}
} public class ListMovieFinder :IMovieFinder
{
public List<Movie> FindAll()
{
return new List<Movie>
{
new Movie
{
Name = "Die Hard.wmv"
},
new Movie
{
Name = "My Name is John.MPG"
}
};
}
} public interface IMovieFinder { List<Movie> FindAll() }

二、改造代码,去除MovieFinderFactory

在应用Autofac替换MovieFinderFactory之前,我们先从代码中去掉MovieFinderFactory, 改动之后的代码是这样:

public class MPGMovieLister
{
private readonly IMovieFinder _movieFinder;
//增加了构造函数,参数是IMovieFinder对象
public MPGMovieLister(IMovieFinder movieFinder)
{
_movieFinder = movieFinder;
} public Movie[] GetMPG()
{
var allMovies = _movieFinder.FindAll();
return allMovies.Where(m => m.Name.EndsWith(".MPG")).ToArray();
}
} public interface IMovieFinder
{
List<Movie> FindAll()
}

  我们去掉了工厂类MovieFinderFactory, 改造了MPGMovieLister, 添加了一个构造函数, 构造函数要求使用MPGMovieLister时,需要提供一个IMovieFinder的实例。

三、应用Autofac替代工厂类

应用Autofac改造上面的代码。

第一步: 从Nuget中添加Autofac引用

第二步:

* 创建一个ContainerBuilder对象(ContainerBuilder从字面的意思就是用来创建Container(容器)的,而Conainter就是我们从中取各种我们需要对象的地方)

* 注册我们后面将从容器中取出对象的类型。

代码是这样:

var builder = new ContainerBuilder();
builder.RegisterType<ListMovieFinder>().As<IMovieFinder>();//注册ListMovieFinder类型
builder.RegisterType<MPGMovieLister>();//注册MPGMovieLister类型

* 创建容器

_container = builder.Build();

第三步: 在程序中使用 _container容器:

var lister = _container.Resolve<MPGMovieLister>();
foreach (var movie in lister.GetMPG())
{
Console.WriteLine(movie.Name);
}

理解一下Autofac为我们在背后做了什么:

首先我们注册了类型ListMovieFinder和MPGMovieLister,这样容器就能够知道如何创建这两种类型的实例了。(类其实是创建对象的模板,当我们把模板注册给Autofac, 它就会遵循这个模板为我们提供实例)

后面的代码中,我们调用Resolve方法,取出一个MPGMovieLister的实例。

_container.Resolve<MPGMovieLister>();

这里还有一个需要解释的,对于MPGMovieLister类型,我们为Autofac提供了类型, 但是当Autofac创建MPGMovieLister的实例, 调用它的构造函数的时候,却遇到了问题:

它的构造函数需要提供一个IMovieFinder的实例作为参数, 聪明的Autofac要在自己的容器里找找,看看没有有办法提供一个IMovieFinder的实例。

这个时候Autofac会发现我们注册过ListMovieFinder且通过AsImplementedInterfaces()方法,指明了就是为接口IMovieFinder提供实例的。

所以Autofac会创建一个ListMovieFinder的实例,作为创建MPGMovieLister时,提供给构造函数的参数。

builder.RegisterType<ListMovieFinder>().AsImplementedInterfaces();

四、当需求发生变动Autofac如何应对?

上面的例子中类ListMovieFinder实现了IMovieFinder接口, 实际运行中由它来提供数据。

假如这个时候,我们要从数据库中获取数据,怎么办?

非常简单,创建一个类DBMovieFinder继承IMovieFinder接口, 然后注册给Autofac就可以了。

var builder = new ContainerBuilder();
builder.RegisterType<ListMovieFinder>().AsImplementedInterfaces();
//这里注册了DBMovieFinder, 这个类继承IMovieFinder接口。因为它也使用了AsImplementedInterfaces,它会覆盖ListMovieFinder的注册。
builder.RegisterType<DBMovieFinder>().AsImplementedInterfaces();
builder.RegisterType<MPGMovieLister>();
_container = builder.Build();

五、Autofac对程序架构的影响

常见的程序架构大概是: UI层, 业务逻辑层, 持久层(数据层)。

我们可用Autofac作为不同层之间的中间人,让UI层依赖于业务逻辑层的抽象接口,业务逻辑层依赖于持久层的接口,而实际运行过程中的实例都由Auotfac来提供。

这样就能够解除不同层之间的依赖,将所有的注册类型的操作在一个核心函数或者核心类中实现,那么只要修改这个函数或者类就能够非常方便的让它们之间的依赖关系发生变化。

比如 在一个大的项目中,持久层和业务逻辑层是并行开发的,而且是不同团队开发,这个时候业务逻辑开发团队的人在没有持久层代码的情况下,如何开始呢?

我们只要定义好持久层的接口, 业务逻辑团队再写一些Stub类(桩类)来实现这些接口,让这些Stub类来替换真正的持久层,所要做的就只是简单的把这些Stub类型注册到Autofac中就可以了。同时做业务逻辑层的单元测试也非常容易了。

六、 总结

从上面的例子可以看出,使用IoC对于复杂的项目来说,非常有意义,能够为我们搭建一个好的开发层次。

同时,在使用过程中,还能够发现Autofac有以下优点:

1. 可以使用C#代码来完成注册配置,非常方便而且便于调试。(使用xml配置,往往容易出现格式不对,或者其它问题,非常难于调试和排错)

2. 非常聪明,能够自动装配(发现构造函数需要的必须参数的时候,会自己想办法解决)

IoC容器Autofac之实例优化(三)的更多相关文章

  1. IoC容器Autofac之实例引入(一)

    先不必尝试理解IOC,先来看段代码. 一.一个没有使用IoC的例子 public class MPGMovieLister { public Movie[] GetMPG() { var finder ...

  2. Ioc容器Autofac系列(1)-- 初窥

     一.前言 第一次接触Autofac是因为CMS系统--Orchard,后来在一个开源爬虫系统--NCrawler中也碰到过,随着深入了解,我越发觉得Ioc容器是Web开发中必不可少的利器.那么,Io ...

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

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

  4. IoC容器Autofac学习笔记

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

  5. [转]Ioc容器Autofac

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

  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. .net core2.0下Ioc容器Autofac使用

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

  8. IOC容器 - Autofac概述

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

  9. ASP.NET中IOC容器Autofac(依赖注入DI 控制反转IOC)

    IOC的一个重点是在程序运行中,动态的向某个对象提供它所需要的其他对象.这一点是通过DI来实现的.Autofac则是比较流行的一款IOC容器. IoC和DI有什么关系呢?其实它们是同一个概念的不同角度 ...

随机推荐

  1. XMLHttpRequest取得响应

    RresponseText:获得字符串形式的响应数据 responseXML:获得XML形式的响应数据 status和statusText:以数字和文本形式返回HTTP状态码 getAllRespon ...

  2. 文本输入框的两种div+css的写法

    1.扁平化的设计风格.--淘宝   直接使用input.对其设置height.padding.使鼠标居中又不会占满输入框.       2.背景是图片的设计.--百度   试用span将input包裹 ...

  3. javascsript 去除数组重复数据

    function uniqid(arr){ var newArr = []; var c; for(var i = 0 ;i <= arr.length ;i++){ c = false; fo ...

  4. Oracle自动备份脚本

    set mydate=%date:~0,4%%date:~5,2%%date:~8,2%exp 用户名/密码@实例名 file=D:\mydata_%mydate%.dmp owner=用户名 log ...

  5. C#远程获取/读取网页内容

    转载自 :http://blog.csdn.net/gisfarmer/article/details/2836904 using System; using System.Collections.G ...

  6. Link all references for a local rename (does not change references in other files)

    这是一个十分easy的问题 错误原因  : import  Android.R; 把这句话去掉 ctrl + shift+o  引进一个  项目对应的R文件 R存在于gen文件夹下 可以找到 layo ...

  7. Js 时间间隔计算(间隔天数)

    function GetDateDiff(startDate,endDate)  {      var startTime = new Date(Date.parse(startDate.replac ...

  8. Java学习笔记--多线程

    rollenholt的博文:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html 弹球例子: 0. 创建Bounce框架 ...

  9. 163k地方门户网站系统自动审核信息脚本

    本代码实现对163k地方门户网站系统发布信息的自动审核,以及对内容中链接全过滤 软件安装 Python 安装 http://www.python.org/download/ pymssql安装 htt ...

  10. format %x invalid or incompatible with argument问题解决方法

    现在还有好多朋友在用Protel 99se来画图,可是在现在的双核或四核电脑上运行Protel出现错误并且弹出对话框:“format '%x' invalid or incompatible with ...