IoC容器Autofac之实例优化(三)

时间:2022-10-03 10:31:19

回顾之前的代码

//这个类的作用是筛选出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引用

IoC容器Autofac之实例优化(三)

第二步:

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

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

代码是这样:

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

* 创建容器

_container = builder.Build();

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

IoC容器Autofac之实例优化(三)
var lister = _container.Resolve<MPGMovieLister>();
foreach (var movie in lister.GetMPG())
{
Console.WriteLine(movie.Name);
}
IoC容器Autofac之实例优化(三)

理解一下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之实例引入&lpar;一&rpar;

    先不必尝试理解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 &plus; Asp&period;net MVC &plus; 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. &lbrack;转&rsqb;Ioc容器Autofac

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

  6. IoC容器Autofac&lpar;5&rpar; - Autofac在Asp&period;net MVC Filter中的应用

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

  7. &period;net core2&period;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&period;NET中IOC容器Autofac&lpar;依赖注入DI 控制反转IOC&rpar;

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

随机推荐

  1. 将UIview描画成虚线等&period;

    - (UIView *)lineView{ if (!_lineView) { _lineView = [UIView new]; // _lineView.backgroundColor = UIC ...

  2. WCF 套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的

    一个项目需要用到推送的功能,就是服务器主动推送数据给多台客户机.于是采用了WCF的双工通讯netTcpBinding 写好的项目,在本机测试都没有问题. 如果放在局域网内测试,问题出来了:先是安全性问 ...

  3. ps&comma; top&comma; pstree

    ps 查看当前终端所启动的进程, 不加选项只查看当前终端的进程 PID TTY TIME CMD 2398 pts/1 00:00:00 bash 3625 pts/1 00:00:00 ps #PI ...

  4. MVC3&sol;4 自定义HtmlHelper截断文本内容&lpar;截取&rpar;

    在MVC目录下新建一个名为 Extersions  的文件夹,在该文件夹中新建一个截断文本类,取名为:CutOfTextExtersions 该类代码如下: using System; using S ...

  5. SCVMM之Windows Server2012 R2新功能

    在Windows Server 2012 R2中可以通过使用共享的虚拟硬盘VHDX文件的方法来模拟IP SAN,来为虚拟机创建群集提供共享存储.这样为虚拟机创建群集时就不用再像以前一样通过使用软件模拟 ...

  6. 利用绝对定位与margin实现元素居中

    例: 要让一个width:100px ; height: 100px;的div,相对body居中. div{ width:100px; height:100px; border: 1px solid ...

  7. 你们都是怎么阅读android系统源码的,用什么工具?

    如果是eclipse,可以建立java或者c++工程,把framework源码导入.packages目录下的可以建立android工程.sourceinsight的话,建立工程把相应模块的代码添加进去 ...

  8. 如何本地测试例如QQ登录等第三方接口

    前言:现在基本是个网站就会集成第三方的一些接口,比如QQ登录.分享等等.但是在开发的时候,尤其是没有这方面经验的开发人员来说,调试流程时会显得迷茫,不知道怎么调试.这里就个人的这方面学习摸索做一个总结 ...

  9. Beta敏捷冲刺每日报告——Day3

    1.情况简述 Beta阶段Scrum Meeting 敏捷开发起止时间 2017.11.4 00:00 -- 2017.11.5 00:00 讨论时间地点 2017.11.4 晚9:30,电话会议会议 ...

  10. 敏捷测试(3)--基于story的敏捷基础知识

    基于story的敏捷基础知识----story编写 为什么使用Story? 软件行业40年多来,需求分析技术已经很成熟了,但是MRD驱动的过程不堪重负.因为往往MRD编写会占去很多时间,MRD评审又会 ...