一切福田,不離方寸,從心而覓,感無不通。

一步一步学EF系列【6、IOC 之AutoFac】

前言

之前的前5篇作为EF方面的基础篇,后面我们将使用MVC+EF 并且使用IOC ,Repository,UnitOfWork,DbContext来整体来学习。因为后面要用到IOC,所以本篇先单独先学习一下IOC,我们本本文单独主要学习Autofac,其实对于Autofac我也是边学边记录。不对的地方,也希望大家多多指导。

个人在学习过程中参考博客:

AutoFac文档:http://www.cnblogs.com/wolegequ/archive/2012/06/09/2543487.html

AutoFac使用方法总结:Part I:http://niuyi.github.io/blog/2012/04/06/autofac-by-unit-test/

为什么使用AutoFac?

Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个:

优点:

  • 它是C#语言联系很紧密,也就是说C#里的很多编程方式都可以为Autofac使用,例如可以用Lambda表达式注册组件
  • 较低的学习曲线,学习它非常的简单,只要你理解了IoC和DI的概念以及在何时需要使用它们
  • XML配置支持
  • 自动装配
  • 与Asp.Net MVC 集成
  • 微软的Orchad开源程序使用的就是Autofac,从该源码可以看出它的方便和强大

上面的优点我也是拷的别人文章里面的,上面的这个几乎所有讲Autofac博文都会出现的。这个也是首次学习,所以我们还是记录的细一点。

怎么使用Autofac

通过VS中的NuGet来加载AutoFac,引入成功后引用就会出现Autofac。

imageimage

1、我们做一个简单的例子先用一下

就拿数据访问来做案例把,一个数据请求有两个类,一个是Oracle 一个是SQLSERVER。我们在使用的时候可以选择调用那个数据库。

1.1 我们先定义一个数据访问的接口和访问类。

 

 

 

最普通的方式大家都会的吧! 如果最普通的方式调用SQLSERVER怎么写?


 

改进一下代码。我们在加入一个DataSourceManager类来看一下

这样写的好处是什么,这样加入加入新的数据源,只用调用的时候传入这个对象就可以,就会自动创建一个对应的对象。那接下如果要调用SQLSERVER怎么写。看代码

1.2 注入实现构造函数注入

上面的DataSourceManager的动态创建的方式就是因为又有个带IDataSource的参数的构造函数,只要调用者传入实现该接口的对象,就实现了对象创建。

那我们看看怎么使用AutoFac注入实现构造函数注入

 

上面的就是AutoFac构造函数注入,他给IDataSource注入的是Sqlserver所以我们调用的数据,返回的就是Sqlserver数据。那下面我们具体的了解一下AutoFac的一些方法

1.3 Autofac方法说明


var builder = new ContainerBuilder();
//builder.RegisterType<DataSourceManager>();
builder.RegisterType<Sqlserver>().As<IDataSource>();

using (var container = builder.Build())
{
var manager = container.Resolve<IDataSource>();
Console.WriteLine(manager.GetData());

Console.ReadLine();
}

1
2
3
4
5
6
7
8
var builder = new ContainerBuilder();
builder.RegisterType<Sqlserver>().Named<IDataSource>("SqlServer"); builder.RegisterType<Oracle>().Named<IDataSource>("Oracel");
using (var container = builder.Build())
{
   var manager = container.ResolveNamed<IDataSource>("Oracel");
   Console.WriteLine(manager.GetData());
   Console.ReadLine();
}

image运行后的代码。


container.ResolveNamed<IDataSource>("Oracel"); 就是解析IDataSource的命名实例Oracel。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
IDataSource _ds;
string Name;
 /// <summary>
 /// 根据传入的类型动态创建对象
 /// </summary>
 /// <param name="ds"></param>
 public DataSourceManager(string name, IDataSource ds)
 {
     _ds = ds;
     Name = name;
 }
 public string GetData()
 {
     returnName + ":" + _ds.GetData();
 }

我把DataSourceManager的构造方法加了个name参数,然后我调用的时候:

运行后的代码:

image

 

1.4 通过配置的方式使用AutoFac

在演示一下怎么通过配置文件来配置注册。这块就简单讲,下面的是我的web.config。

 

后台的调用代码


new ConfigurationSettingsReader("autofac"

这里需要注意的是需要引用Autofac.Configuration.dll,否则没有办法使用ConfigurationSettingsReader。

还有一个需要注意的就是你的配置文件要命名空间,类名要写对。

动手尝试一下吧!

 

MVC下面使用Autofac

   引用和上面的控制台程序的原理是一模一样的。但是区别就在于要多添加一个引用

imageimage

案例还是用上面的案例。我是把之前的接口和类拷贝到MVC项目里面作为下面演示。代码就不在写出来了,一模一样的。

1、首先在函数Application_Start() 注册自己的控制器类

MVC下怎么配置可以直接看如下代码,我把注释写的也很详细。

需要解释的是:

1、大家看下面的这句,这句的作用就是再MVC下面你必须要注册一下Controller,否则没有办法注入。

我们通过使用RegisterControllers就可以解决。那如果不用RegisterControllers 我就想一个个注册的话怎么弄?学技术有时候不要只管会用有的时候你也要理解人家提供的方法背后是怎么做的。看到这里你知道怎么做么?先考虑1分钟,不要记得往下看。答案其实在上面讲控制台程序使用Autofac的时候已经讲过了。好吧,我来详细讲一下,我先把之前控制台程序的代码贴出来。


public DataSourceManager(string

 

看到了吗?container.Resolve<DataSourceManager>()这里通过Resolve解析DataSourceManager实例,对于DataSourceManager类型,我们为Autofac提供了类型, 但是当Autofac创建DataSourceManager的实例, 调用它的构造函数的时候,它的构造函数需要提供一个IDataSource的实例作为参数的,Autofac会在自己的容器里,找注册过IDataSource的实例,并且通过AsImplementedInterfaces()方法,指明为接口IDataSource提供的实例。然后作为创建DataSourceManager时,提供给构造函数的参数。这整个原理不知道这样讲你能听懂吗?

大家上面提出的如果不用RegisterControllers来,需要手动添加怎么做?答案就是要写若干个这个方法。

builder.RegisterType<DefaultController>().InstancePerDependency();注:DefaultController 控制器的名称,你可要试着把RegisterControllers删除掉,用上面的这句来尝试一下。但是实际的项目中最好是用RegisterControllers。

2、如果没有写builder.RegisterControllers<> ,而且控制器也没有通过builder.RegisterType<>注册, 你会看到如下的错误

image

整个MVC 使用autofac配置的工作就完成了。那接下来直接来看代码里面怎么使用。

2、   添加控制器,并注入依赖代码

整个功能请求的数据添加到ViewBag然后在页面上面显示出来,也比较简单的。

运行后的效果:

image

成功了!

补充一下:

上面的列子演示的是构造函数注入,那看看能否改成属性注入。

看如下代码,IDataSource 加上get;set就变成属性了:

 

 

如果现在任何地方都不改的情况下,你看看会报什么错,是不是提醒ds为null,那怎么支持属性注入呢! 我看了好久

 

把Global.asax里面的这句改成如上这句 就好了!

 

补充,自动注入

Autofac提供一个RegisterAssemblyTypes方法。它会去扫描所有的dll并把每个类注册为它所实现的接口。既然能够自动注入,那么接口和类的定义一定要有一定的规律。我们可以定义IDependency接口的类型,其他任何的接口都需要继承这个接口。比如

 

 

 

1
2
3
4
5
6
7
8
/// <summary>
/// 业务逻辑实现——岗位管理
/// </summary>
public class PostService : IDependency
{
  public IPostService postService { getset; }
  ........
 }

 

自动注入原理说明:

首先我们去找到所有Dll,再去找到实现了IDependency接口的类,然后使用RegisterAssemblyTypes进行注入。

 

结语

终于把AutoFac这篇完成了,有不对的地方,还希望各位能多多指点,共同学习进步。初次写系列文章,真的有点佩服在博客园分享的各位大牛了,这个真的是很耗费时间和精力的,以后更应该尊重别人的知识分享。

 

from:https://www.cnblogs.com/liupeng/p/4806184.html