Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高。
源码下载地址https://github.com/autofac/Autofac
控制反转(IoC/Inverse Of Control): 调用者不再创建被调用者的实例,由autofac框架实现(容器创建)所以称为控制反转。
依赖注入(DI/Dependence injection) : 容器创建好实例后再注入调用者称为依赖注入。
安装Autofac
1、InstancePerDependency
对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。
2、InstancePerLifetimeScope
在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。
3、InstancePerMatchingLifetimeScope
在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。
4、InstancePerOwned
在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。
5、SingleInstance
每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。
6、InstancePerHttpRequest
在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。
在MVC中使用项目代码
1、Repository继承自IRepository、Services继承自IServices
2、设置Repository和Services的生成路径,为MVC网站的bin目录下
3、在App_Start中添加如下代码
namespace duo.CRM.Site
{
using Autofac;
using Autofac.Integration.Mvc;
using Common;
using System.Reflection;
using System.Web.Mvc;
public class AutofacConfig
{
/// <summary>
/// 负责调用autofac框架实现业务逻辑层和数据仓储层程序集中的类型对象的创建
/// 负责创建MVC控制器类的对象(调用控制器中的游蚕构造函数),接管DefaultControllerFactory工作
/// </summary>
public static void Register()
{
//1.0实例化一个autofac的创建容器
var builder = new ContainerBuilder();
//2.0告诉autofac框架,将来要创建控制器类存放在哪个程序集
Assembly controllerAss = Assembly.Load("duo.CRM.Site");
builder.RegisterControllers(controllerAss);
//3.0告诉autofac框架注册仓储层所在程序集中的所有类的对象实例
Assembly respAss = Assembly.Load("duo.CRM.Repository");
//创建respAss中的所有类的instance以此类的实现接口存储
builder.RegisterTypes(respAss.GetTypes()).AsImplementedInterfaces();
//4.0告诉autofac框架注册业务逻辑所在程序集中的所有类的对象实例
Assembly serAss = Assembly.Load("duo.CRM.Services");
//创建respAss中的所有类的instance以此类的实现接口存储
builder.RegisterTypes(serAss.GetTypes()).AsImplementedInterfaces();
//builder.RegisterType(typeof(sysFunctionServices)).As(typeof(IsysFunctionServices));
//5.0创建autofac的容器
var container = builder.Build();
//将container对象缓存到HttpRuntime.cache中,并且永久有效
CacheMgr.SetData(Keys.AutofacContainer, container);
//Resolve方法可以从autofac容器中获取指定IsysFunctionServices的具体实现类的实体对象
//container.Resolve<IServices.IsysFunctionServices>();
//6.0将MVC的控制器对象实例 交由autofa来创建
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
//我们知道控制器的创建是调用MVC默认的控制器工厂,默认的控制器工厂是调用控制器类的无参构造函数
//可是我们如果要使用AutoFac自动工厂,将对象通过构造函数注入类中,那么这个构造函数就需要带参数
//如果我们将控制器的无参构造函数删除,保留带参数的构造函数,MVC默认的控制器工厂来创建控制的时候
//就会去调用无参的构造函数,可是这时候发现没有无参的构造函数于是就报“没有为该对象定义无参数的构造函数”错误
//既然报错,那我们如果保留无参的构造函数,同时在声明一个带参数的构造函数是否可行呢?
//答案;行是行,但是创建控制器的时候,MVC默认的控制器工厂调用的是无参构造函数,它并不会去调用有参的构造函数
//这时候,我们就只能将AutoFac它的控制器工厂替换调用MVC默认的控制器工厂(控制器由AutoFac的控制器工厂来创建)
//而AutoFac控制器工厂在创建控制的时候只会扫描带参数的构造函数,并将对象注入到带参数的构造函数中
//AutofacDependencyResolver这个控制器工厂是继承了 IDependencyResolver接口的,而IDependencyResolver接口是MVC的东西
//MVC默认的控制器工厂名字叫:DefaultControllerFactory
}
}
}
4、在Global.asax文件中注册
5、通过构造函数注入实现DI