IoC容器Autofac之实例优化(三)
回顾之前的代码
//这个类的作用是筛选出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之实例优化(三)的更多相关文章
- IoC容器Autofac之实例引入(一)
先不必尝试理解IOC,先来看段代码. 一.一个没有使用IoC的例子 public class MPGMovieLister { public Movie[] GetMPG() { var finder ...
- Ioc容器Autofac系列(1)-- 初窥
一.前言 第一次接触Autofac是因为CMS系统--Orchard,后来在一个开源爬虫系统--NCrawler中也碰到过,随着深入了解,我越发觉得Ioc容器是Web开发中必不可少的利器.那么,Io ...
- IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)
转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html 有修改 Autofac通过Controller默认构造 ...
- IoC容器Autofac学习笔记
一.一个没有使用IoC的例子 IoC的全称是Inversion of Control,中文叫控制反转.要理解控制反转,可以看看非控制反转的一个例子. public class MPGMovieList ...
- [转]Ioc容器Autofac
本文转自:http://www.cnblogs.com/hkncd/archive/2012/11/21/2780041.html Ioc容器Autofac系列(1)-- 初窥 前言 第一次接触A ...
- IoC容器Autofac(5) - Autofac在Asp.net MVC Filter中的应用
Autofac结合EF在MVC中的使用,上一篇IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)已经介绍了.但是只是MVC中Co ...
- .net core2.0下Ioc容器Autofac使用
.net core发布有一段时间了,最近两个月开始使用.net core2.0开发项目,大大小小遇到了一些问题.准备写个系列介绍一下是如何解决这些问题以及对应技术.先从IOC容器Autofac开始该系 ...
- IOC容器 - Autofac概述
Autofac是比较出名的Ioc容器之一,熟悉Orchard的应该熟知.本文直接介绍autofac用法 一.开始 1.NuGet添加或者直接http://code.google.com/p/autof ...
- ASP.NET中IOC容器Autofac(依赖注入DI 控制反转IOC)
IOC的一个重点是在程序运行中,动态的向某个对象提供它所需要的其他对象.这一点是通过DI来实现的.Autofac则是比较流行的一款IOC容器. IoC和DI有什么关系呢?其实它们是同一个概念的不同角度 ...
随机推荐
- Layer中自定义属性的动画
转载自:http://blog.jobbole.com/69211/ 默认情况下,CALayer 及其子类的绝大部分标准属性都可以执行动画,无论是添加一个 CAAnimation 到 Layer(显式 ...
- seajs初尝 加载jquery返回null解决学习日志含示例下载
原文地址:http://www.tuicool.com/articles/bmuaEb 如需demo示例,请点击下方链接下载: http://yunpan.cn/cVEybKs8nV7CF 提取码 ...
- C#类型基础——学习笔记一
1.C#中的类型一共分两类,一类是值类型,一类是引用类型.2.结构类型变量本身就相当于一个实例.3.调用结构上的方法前,需要对其所有的字段进行赋值.4.所有元素使用前都必须初始化.5.(结构类型)ne ...
- 7 RandomAccessFile读取文件内容保存--简单例子(需要验证)
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; /** * 读取动态产生的文件内容 */ publ ...
- 基于nginx的rtmp的服务器(nginx-rtmp-module)
一,首先下载安装nginx需要依赖的库文件: 1.1,选定源码目录 选定目录 /usr/local/RTMP cd /usr/local/RTMP 1.2,安装PCRE库 cd /usr/local/ ...
- 如何在WebSocket类中访问Session
我最近正在做一个基于websocket的webQQ,最后代码会开源带github上,所以过程中我就不贴所有的代码啦~就贴问题的关键. 我在WebSocket里发消息的时候需要用到session,因为在 ...
- js实现点击ul/li等改变背景颜色
今天项目遇到了标题所说的问题,找到一篇很高效的例子,值得学习. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//E ...
- Constructing Roads--hdu1102
Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 利用Azure高级存储搭建高性能Linux服务器(2)
我们首先来测试随机写的IOPS,可以看到随机写的IOPS可以达到,顺序写的IOPS可以达到: $ sudo fio -filename=/data/testfile -direct=1 -iodept ...
- CloudStack核心类ApiServlet、ApiServer、ApiDispatcher、GenericDaoBase源码分析
ApiServlet 首先从整体上看下ApiServlet,Outline视图如下, 一.注意@Inject依赖的是javax.inject.jar,它和spring的@Autowired的区别在于使 ...