一、简介

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

目的

1.依赖注入的目的是为了解耦。

2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置。

3.控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。

4. 微软的DependencyResolver如何创建controller

生命周期

1、InstancePerDependency

对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。

官方文档解释:Configure the component so that every dependent component or call to Resolve() gets a new, unique instance (default.)

2、InstancePerLifetimeScope

在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。

官方文档解释:Configure the component so that every dependent component or call to Resolve() within a single ILifetimeScope gets the same, shared instance. Dependent components in different lifetime scopes will get different instances.

3、InstancePerMatchingLifetimeScope

在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。

官方文档解释:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope tagged with any of the provided tags value gets the same, shared instance. Dependent components in lifetime scopes that are children of the tagged scope will share the parent's instance. If no appropriately tagged scope can be found in the hierarchy an DependencyResolutionException is thrown.

4、InstancePerOwned

在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。

官方文档解释:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope created by an owned instance gets the same, shared instance. Dependent components in lifetime scopes that are children of the owned instance scope will share the parent's instance. If no appropriate owned instance scope can be found in the hierarchy an DependencyResolutionException is thrown.

5、SingleInstance

每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。

官方文档解释:Configure the component so that every dependent component or call to Resolve() gets the same, shared instance.

6、InstancePerHttpRequest  (新版autofac建议使用InstancePerRequest)

在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。
官方文档解释:Share one instance of the component within the context of a single HTTP request.

二、常用方法

(1)builder.RegisterType<Object>().As<Iobject>():注册类型及其实例。例如下面就是注册接口IDAL的实例SqlDAL
2)IContainer.Resolve<IDAL>():解析某个接口的实例。例如上面的最后一行代码就是解析IDAL的实例SqlDAL
(3)builder.RegisterType<Object>().Named<Iobject>(string name):为一个接口注册不同的实例。有时候难免会碰到多个类映射同一个接口,比如SqlDAL和OracleDAL都实现了IDAL接口,为了准确获取想要的类型,就必须在注册时起名字。
(4)IContainer.ResolveNamed<IDAL>(string name):解析某个接口的“命名实例”。例如上面的最后一行代码就是解析IDAL的命名实例OracleDAL
(5)builder.RegisterType<Object>().Keyed<Iobject>(Enum enum):以枚举的方式为一个接口注册不同的实例。有时候我们会将某一个接口的不同实现用枚举来区分,而不是字符串,
(6)IContainer.ResolveKeyed<IDAL>(Enum enum):根据枚举值解析某个接口的特定实例。例如上面的最后一行代码就是解析IDAL的特定实例OracleDAL
(7)builder.RegisterType<Worker>().InstancePerDependency():用于控制对象的生命周期,每次加载实例时都是新建一个实例,默认就是这种方式
(8)builder.RegisterType<Worker>().SingleInstance():用于控制对象的生命周期,每次加载实例时都是返回同一个实例
(9)IContainer.Resolve<T>(NamedParameter namedParameter):在解析实例T时给其赋值

三、文件配置

通过配置的方式使用
(1)先配置好配置文件
<?xml version="1.0"?><configuration><configSections><section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/></configSections><autofac defaultAssembly="ConsoleApplication1"><components><component type="ConsoleApplication1.SqlDAL, ConsoleApplication1" service="ConsoleApplication1.IDAL" /></components></autofac></configuration>

(2)读取配置实现依赖注入(注意引入Autofac.Configuration.dll)
static void Main(string[] args){ContainerBuilder builder = new ContainerBuilder();builder.RegisterType<DBManager>();builder.RegisterModule(new ConfigurationSettingsReader("autofac"));using (IContainer container = builder.Build()){DBManager manager = container.Resolve<DBManager>();manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')"); } 

四、示例

MVC5示例中实现的功能有:程序集注册、按服务注册、属性注入、泛型注入

global.cs

    public class MvcApplication : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);InitDependency();StackExchange.Profiling.EntityFramework6.MiniProfilerEF6.Initialize();}private void InitDependency(){ContainerBuilder builder = new ContainerBuilder();Type baseType = typeof(IDependency);// 自动注册当前程序集//builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();// 注册当前程序集Assembly assemblies = Assembly.GetExecutingAssembly();builder.RegisterAssemblyTypes(assemblies).Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract).AsImplementedInterfaces().InstancePerLifetimeScope();//保证对象生命周期基于请求//注册引用的程序集//var assemblyList = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly => assembly.GetTypes().Any(type => type.GetInterfaces().Contains(baseType)));//var enumerable = assemblyList as Assembly[] ?? assemblyList.ToArray();//if (enumerable.Any())//{//    builder.RegisterAssemblyTypes(enumerable)//        .Where(type => type.GetInterfaces().Contains(baseType))//        .AsImplementedInterfaces().InstancePerLifetimeScope();//}//注册指定的程序集//自动注册了IStudentService、IUserServicebuilder.RegisterAssemblyTypes(Assembly.Load("AppService"), Assembly.Load("AppService")).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces();//一、Type注册服务 builder.RegisterType<CourseService>().As<ICourseService>();builder.RegisterType<UserService>().AsSelf();// 注入类本身,等价于.As<UserService>();builder.RegisterType<ScoreManage>().AsImplementedInterfaces();//批量注册,等价于.As<IEnglishScoreManage>().As<IMathematicsScoreManage>();//二、Named注册服务//builder.RegisterType<ChineseScorePlusManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString());// 一个接口与多个类型关联//builder.RegisterType<ChineseScoreManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString());// 一个接口与多个类型关联//三、Keyed注册服务builder.RegisterType<ChineseScorePlusManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus);// 一个接口与多个类型关联builder.RegisterType<ChineseScoreManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScore);// 一个接口与多个类型关联//泛型注册,可以通过容器返回List<T> 如:List<string>,List<int>等等//builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope();//生命周期//builder.RegisterType<StudentService>().As<IStudentService>().InstancePerLifetimeScope(); //基于线程或者请求的单例..就是一个请求 或者一个线程 共用一个//builder.RegisterType<StudentService>().As<IStudentService>().InstancePerDependency(); //服务对于每次请求都会返回单独的实例//builder.RegisterType<StudentService>().As<IStudentService>().SingleInstance(); //单例.. 整个项目公用一个//builder.RegisterType<StudentService>().As<IStudentService>().InstancePerRequest(); //针对MVC的,或者说是ASP.NET的..每个请求单例
             builder.RegisterType<ServiceGetter>().As<IServiceGetter>();//用于一个接口与多个类型关联
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();//属性注入,未注册将出现“没有为该对象定义无参数的构造函数。”
             builder.RegisterType<TestDbContext>().As<IDbContext>().InstancePerLifetimeScope();builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();//泛型注入//builder.RegisterFilterProvider(); //注入特性,特性里面要用到相关的服务IContainer container = builder.Build();DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//生成容器并提供给MVC
        }protected void Application_BeginRequest(){if (Request.IsLocal)//这里是允许本地访问启动监控,可不写
            {MiniProfiler.Start();}}protected void Application_EndRequest(){MiniProfiler.Stop();}}

控制器

public class HomeController : Controller{private readonly IStudentService _studentService;private readonly ITeacherService _teacherService;private readonly IUserService _userService;public readonly UserService UserService;private readonly IEnglishScoreManage _englishScoreManage;private readonly IMathematicsScoreManage _mathematicsScoreManage;private IServiceGetter getter;public ICourseService CourseService { get; set; }private readonly IRepository<Student> _studentRrepository;public HomeController(IStudentService studentService, IUserService userService, ITeacherService teacherService, UserService userService1, IMathematicsScoreManage mathematicsScoreManage, IEnglishScoreManage englishScoreManage, IServiceGetter getter, IRepository<Student> studentRrepository){_studentService = studentService;_userService = userService;_teacherService = teacherService;this.UserService = userService1;_mathematicsScoreManage = mathematicsScoreManage;_englishScoreManage = englishScoreManage;this.getter = getter;_studentRrepository = studentRrepository;}public ActionResult Index(){var name = "";var student = _studentRrepository.GetById("4b900c95-7aac-4ae6-a122-287763856601");if (student != null){name = student.Name;}ViewBag.Name = _teacherService.GetName();ViewBag.UserName1 = _userService.GetName();ViewBag.UserName2 = UserService.GetName();ViewBag.StudentName = _studentService.GetName() + "-" + name;ViewBag.CourseName = CourseService.GetName();ViewBag.EnglishScore = _englishScoreManage.GetEnglishScore();ViewBag.MathematicsScore = _mathematicsScoreManage.GetMathematicsScore();//ViewBag.ChineseScore = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString()).GetScore();//ViewBag.ChineseScorePlus = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString()).GetScore();
ViewBag.ChineseScore = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScore).GetScore();ViewBag.ChineseScorePlus = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus).GetScore();return View();}
}

页面

@{ViewBag.Title = "Home Page";
}<div class="jumbotron"><h1>ASP.NET</h1>
</div><div class="row"><div class="col-md-4"><h2>Teacher: @ViewBag.Name </h2><p>CourseName: @ViewBag.CourseName</p><p></p></div><div class="col-md-4"><h2>User</h2><p>接口注入:@ViewBag.UserName1</p><p>类注入:@ViewBag.UserName2</p></div><div class="col-md-4"><h2>Student: @ViewBag.StudentName</h2><p>English:@ViewBag.EnglishScore</p> <p>Math: @ViewBag.MathematicsScore</p> <p>Chinese: @ViewBag.ChineseScore</p> <p>ChinesePlus:@ViewBag.ChineseScorePlus</p> </div>
</div>

代码下载:https://gitee.com/zmsofts/XinCunShanNianDaiMa/blob/master/EntityFrameworkExtension.rar

注意:codefirst开发,先迁移后才能使用

参考文章:

https://www.cnblogs.com/struggle999/p/6986903.html

https://www.cnblogs.com/gdsblog/p/6662987.html

https://www.cnblogs.com/kissdodog/p/3611799.html

https://www.cnblogs.com/fuyujian/p/4115474.html

http://www.cnblogs.com/tiantianle/category/779544.html

.Net IOC框架入门之三 Autofac相关推荐

  1. .Net IOC框架入门之一 Unity

    一.概述 IOC:英文全称:Inversion of Control,中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection). 作用:将各层的对象以松耦合的方式组织在一 ...

  2. .Net IOC框架入门之二 CastleWindsor

    一.简介 Castle是.net平台上的一个开源项目,为企业级开发和WEB应用程序开发提供完整的服务,用于提供IOC的解决方案.IOC被称为控制反转或者依赖注入(Dependency Injectio ...

  3. .NET领域最为流行的IOC框架之一Autofac

    一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也是用的Autofac. Orchad和Nopcomm ...

  4. 使用注解打造自己的IOC框架

    一.简述 IoC和AOP可谓是后台开发入门必学的知识(Spring相关),但这两者都仅仅只是概念而已,并非具体技术实现,同样的,Android也可以使用IoC和AOP,之前已经写过如何在Android ...

  5. .NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能

    一.前言 ASP.NET Core本身已经集成了一个轻量级的IOC容器,开发者只需要定义好接口后,在Startup.cs的ConfigureServices方法里使用对应生命周期的绑定方法即可,常见方 ...

  6. (转载)VS2010/MFC编程入门之三十六(工具栏:工具栏资源及CToolBar类)

    上一节中鸡啄米讲了菜单及CMenu类的使用,这一节讲与菜单有密切联系的工具栏. 工具栏简介 工具栏一般位于主框架窗口的上部,菜单栏的下方,由一些带图片的按钮组成.当用户用鼠标单击工具栏上某个按钮时,程 ...

  7. ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

    上一篇ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器) ,我们说过ASP.NET Core中自带的IOC容器是属于轻量级的,功能并不是很多,只是提供了基础 ...

  8. 常用Flex IOC框架比较分析【转载】

    IOC(Inversion of Control),也称DI(Dependency Injection),是近年来在软件开发中变得非常流行的一种设计策略.众多的Flex开发者,探索出了诸如Spring ...

  9. VS2013/MFC编程入门之三十四(工具栏:工具栏资源及CToolBar类)

    上一节中讲了菜单及CMenu类的使用,这一节讲与菜单有密切联系的工具栏. 工具栏简介 工具栏一般位于主框架窗口的上部,菜单栏的下方,由一些带图片的按钮组成.当用户用鼠标单击工具栏上某个按钮时,程序会执 ...

最新文章

  1. Active Record
  2. 【Flask】CORS同源问题解决
  3. lnmp的搭建及php加速
  4. 川教版计算机三年级下册教案,川教版小学三年级下册信息技术教案(全册)
  5. source insight 支持lua /ruby
  6. php.ini在哪里 微赞_虚拟主机php.ini在哪?怎么查看php.ini在哪
  7. 二分法在数组内查找数c语言,C++二分法在数组中查找关键字的方法
  8. leetcode3. Longest Substring Without Repeating Characters
  9. oracle case套case,,套用when case
  10. 软考(2)——看图心想编译原理
  11. Android屏幕适配的两种方式
  12. 95-35-010-Topic-Topic 扩容 源码解析
  13. 关于 XHTML 1.0 Transitional//EN 下的Relative问题
  14. visual怎么设置默认运行_神马?游戏和软件不能运行?来3DM一下吧!
  15. 主力吸筹猛攻指标源码_通达信大于9000手大单指标公式,主力吸筹猛攻指标源码...
  16. 前端实习生实习第一天
  17. SVN的介绍、搭建和使用
  18. zotero+better bibtex+overleaf(latex):如何批量导出参考文献及相关设置
  19. 基于Zynq的光流法软硬件协同设计与实现
  20. 身份证识别、驾驶证识别、行驶证识别

热门文章

  1. 工业机器人电柜布线_协作并联,重新注解并联机器人
  2. android studio查看字节码,使用Android studio查看Kotlin的字节码教程
  3. python控制语句中的条件语句_『Python』条件控制语句
  4. USG防火墙单出口接入互联网
  5. 深蓝学院《从零开始手写VIO》作业七
  6. 统计学---掌握数据的整体状态
  7. 【AutoML】当前有哪些可用的AutoML平台?
  8. 中国滤清器制造行业竞争格局分析与发展战略规划研究报告2022年版
  9. 中国数据备份一体机产业未来供需状况及投资潜力价值报告2021年版
  10. 判断vc2005运行库是否以已安装