介绍

Autofac是一款IOC框架,很轻量级性能非常高,自动注入很给力。

NuGet

Autofac:Autofac控制反转容器核心

Autofac.MVC5:提供IDependencyResolver 接口使MVC实现Autofac功能

Autofac.Configuration:允许使用配置来作为Autofac依赖来源

Autofac.Extensions...:Autofac净框架的实现依赖注入的抽象

Autofac.Multitenant:Autofac扩展多租户应用程序的支持

快速预览

注册组件

可以使用Lambda表达式建立单个组件注册,或者进行扫描自动注册。

  1. var builder = new ContainerBuilder();
  2.  
  3. // 注册单一组件
  4. builder.RegisterInstance(new TaskRepository())
  5. .As<ITaskRepository>();
  6. builder.RegisterType<TaskController>();
  7. builder.Register(c => new LogManager(DateTime.Now))
  8. .As<ILogger>();
  9.  
  10. // 进行扫描自动注册
  11. builder.RegisterAssemblyTypes(myAssembly)
  12. .Where(t => t.Name.EndsWith("Repository"))
  13. .AsImplementedInterfaces();
  14.  
  15. var container = builder.Build();

快速依赖

使用Autofac可以进行构造函数注入、属性注入和方法注入。

  1. public class TaskController
  2. {
  3. private ITaskRepository _repository;
  4. private ILogger _logger;
  5. // Autofac 可以自动查找注册值,并通过他们进行服务
  6. public TaskController(
  7. ITaskRepository repository,
  8. ILogger logger)
  9. {
  10. this._repository = repository;
  11. this._logger = logger;
  12. }
  13. }

灵活的模块系统

可以使用XML注册或集成Module进行注册部署

  1. public class CarTransportModule : Module
  2. {
  3. public bool ObeySpeedLimit { get; set; }
  4.  
  5. protected override void Load(ContainerBuilder builder)
  6. {
  7. builder.RegisterType<Car>().As<IVehicle>();
  8. if (ObeySpeedLimit)
  9. builder.RegisterType<SaneDriver>().As<IDriver>();
  10. else
  11. builder.RegisterType<CrazyDriver>().As<IDriver>();
  12. }
  13. }
  1. <!-- 进行XML部署 -->
  2. <autofac>
  3. <module type="CarTransportModule">
  4. <properties>
  5. <property name="ObeySpeedLimit" value="true" />
  6. </properties>
  7. </module>
  8. </autofac>

简单的扩展方式

Autofac提供激活事件,让你知道激活时组件或发布,允许大量定义和少量代码

  1. var builder = new ContainerBuilder();
  2.  
  3. // 一旦监听器已全面建成并随时可以使用,自动启动监听
  4. builder.RegisterType<Listener>()
  5. .As<IListener>()
  6. .OnActivated(e => e.Instance.StartListening());
  7.  
  8. // 当处理器正在建设但在此之前,随时可以使用,调用初始化方法
  9. builder.RegisterType<Processor>()
  10. .OnActivating(e => e.Instance.Initialize());
  11.  
  12. var container = builder.Build();

入门

构建应用程序

  1. /// <summary>
  2. /// 饮品接口
  3. /// </summary>
  4. public interface IWater
  5. {
  6. string ReturnWater();
  7. }
  8.  
  9. /// <summary>
  10. /// 可乐
  11. /// </summary>
  12. public class Coke : IWater
  13. {
  14. public string ReturnWater()
  15. {
  16. return "可乐";
  17. }
  18. }
  19.  
  20. /// <summary>
  21. /// 牛奶
  22. /// </summary>
  23. public class Milk : IWater
  24. {
  25. public string ReturnWater()
  26. {
  27. return "牛奶";
  28. }
  29. }
  30.  
  31. /// <summary>
  32. /// 茶
  33. /// </summary>
  34. public class Tea : IWater
  35. {
  36. public string ReturnWater()
  37. {
  38. return "茶";
  39. }
  40. }

IWater

  1. #region 人类喝水方法,各模块需Copy此方法来实现
  2.  
  3. /// <summary>
  4. /// 定义人类接口
  5. /// </summary>
  6. public interface IPeople
  7. {
  8. /// <summary>
  9. /// 每个人都会喝水
  10. /// </summary>
  11. string DrinkWater();
  12. }
  13.  
  14. /// <summary>
  15. /// 学生喝可乐,使用构造器注入
  16. /// </summary>
  17. public class Students : IPeople
  18. {
  19. private IWater _water;
  20.  
  21. public Students(IWater water)
  22. {
  23. _water = water;
  24. }
  25.  
  26. public string DrinkWater()
  27. {
  28. return string.Format("学生都爱喝:{0}", _water.ReturnWater());
  29. }
  30. }
  31.  
  32. /// <summary>
  33. /// 老师喝茶,使用属性注入
  34. /// </summary>
  35. public class Teacher : IPeople
  36. {
  37. public IWater Water { get; set; }
  38.  
  39. public string DrinkWater()
  40. {
  41. return string.Format("老师都爱喝:{0}", Water.ReturnWater());
  42. }
  43. }
  44.  
  45. /// <summary>
  46. /// 护士和牛奶,使用方法注入
  47. /// </summary>
  48. public class Nurse : IPeople
  49. {
  50. public IWater Water { get; set; }
  51.  
  52. public string DrinkWater()
  53. {
  54. return string.Format("护士都爱喝:{0}", Water.ReturnWater());
  55. }
  56. }
  57.  
  58. #endregion 喝水

IPeople

添加Autofac

只需要添加核心包 Autofac 即可

启动

在应用程序启动时,需要创建ContainerBuilder来登记依赖组件。

  1. /// <summary>
  2. /// 存储容器
  3. /// </summary>
  4. private static IContainer Container { get; set; }
  5. static void Main(string[] args)
  6. {
  7. if (args == null)
  8. { /* 为了忽略重构提醒 */ }
  9.  
  10. //创建一个Builder
  11. ContainerBuilder builder = new ContainerBuilder();
  12. //暴露出类型和接口的关联
  13. builder.RegisterType<Students>().As<IPeople>();
  14. builder.RegisterType<Coke>().As<IWater>();
  15. //需要保存容器,此处使用属性来保存
  16. Container = builder.Build();
  17.  
  18. //执行方法
  19. Write();
  20. }

Container

执行

在执行过程中,需要利用注册组件,解决他们的寿命范围。

如果组件的寿命范围是永久的话,频繁创建会导致内存移除。可以在IDisposable中进行释放。

  1. private static void Write()
  2. {
  3. using (var scope = Container.BeginLifetimeScope())
  4. {
  5. IPeople people = scope.Resolve<IPeople>();
  6. Console.WriteLine(people.DrinkWater());
  7. }
  8. }

Write

至此,我们的入门教程就完成了。

注册组件

组件:实体    服务:抽象类,接口

ContainerBuilder 中包含的

Register 方法,可以通过lambda表达式设置。

RegisterType 方法,可以通过类型设置。

RegisterInstance 方法,可以通过实例来设置。

  1. builder.RegisterInstance(new TaskRepository())
  2. .As<ITaskRepository>();

每个组件设置服务,都需要使用As()方法。

反射元件

组件产生的反射,通常是由类型进行注册的。我们可以直接注册一个类。此时,会尽可能多的加载类关联的接口。

当使用反射的时候,会自动加载注册类构造函数的参数。

  1. class Program
  2. {
  3. /// <summary>
  4. /// 存储容器
  5. /// </summary>
  6. private static IContainer Container { get; set; }
  7. static void Main(string[] args)
  8. {
  9. if (args == null)
  10. { /* 为了忽略重构提醒 */ }
  11.  
  12. //创建一个Builder
  13. ContainerBuilder builder = new ContainerBuilder();
  14. //将类进行注册,在使用反射时,会加载对应接口
  15. builder.RegisterType<MyComponent>();
  16. builder.RegisterType<Students>().As<IPeople>();
  17. builder.RegisterType<Coke>().As<IWater>();
  18. var container = builder.Build();
  19. using (var scope = container.BeginLifetimeScope())
  20. {
  21. //会自动加载对应接口
  22. var component = container.Resolve<MyComponent>();
  23. //输出结果:两个参数
  24. }
  25. Console.Read();
  26. }
  27. }
  28.  
  29. public class MyComponent
  30. {
  31. public MyComponent() { Console.WriteLine("空构造"); }
  32. public MyComponent(IPeople people) { Console.WriteLine("一个参数"); }
  33. public MyComponent(IPeople people, IWater water) { Console.WriteLine("两个参数"); }
  34. }

MyComponent

我们注册了MyComponent类,然后设置关联。当我们进行反射的时候,会自动加载已经注册的类。

任何通过RegisterType进行注册的类必须是一个具体的类。而As() 后面可以写抽象类或接口实现。

这里,我们还可以手动指定构造函数的调用。例如我们只打算调用一个参数的构造函数。

可以修改为如下

  1. builder.RegisterType<MyComponent>().UsingConstructor(typeof(IPeople));

Lambda表达式

Autofac可以使用lambda表达式做组件注册。

我们可以使用Lambda表达式,做简单的数据映射

  1. builder.Register(c => new Students(c.Resolve<IWater>()));
  2.  
  3. var people = container.Resolve<Students>();
  4. Console.WriteLine(people.DrinkWater());

泛型

Autofac支持泛型类型

  1. public interface IListA<T>
  2. {
  3. void Go();
  4. }
  5.  
  6. public class ListB<T> : IListA<T>
  7. {
  8. public void Go()
  9. {
  10. Console.WriteLine(string.Format("泛型:{0}", typeof(T).Name));
  11. }
  12. }

Entitys

  1. builder.RegisterGeneric(typeof(ListB<>)).As(typeof(IListA<>)).InstancePerLifetimeScope();
  2.  
  3. var list = container.Resolve<IListA<string>>();
  4. list.Go();

RegisterGeneric

重复

如果有多个组件暴露了同样的服务。autofac将使用最后的注册组件,作为该服务的默认提供程序。

builder.RegisterType<Tea>().As<IWater>();
builder.RegisterType<Coke>().As<IWater>();

我们可以使用 PreserveExistingDefaults 进行修正。

  1. builder.RegisterType<Coke>().As<IWater>().PreserveExistingDefaults();

修正后,会把Tea作为默认提供程序。

http://autofac.readthedocs.io/en/latest/register/parameters.html

使用nuget安装,Autofac。

  1. private void OnLoadAutofac()
  2. {
  3. //注册组件
  4. var builder = new ContainerBuilder();
  5. //注册MVC程序集
  6. builder.RegisterControllers(Assembly.GetExecutingAssembly());
  7. //使用Linq依赖注入
  8. builder.RegisterType<ChenxyService>().As<IChenxyService>();
  9. //使用自动注入,后缀为DAL结尾,进行扫描,响应HTTP请求
  10. builder.RegisterAssemblyTypes(typeof(ChenxyDAL).Assembly)
  11. .Where(t => t.Name.EndsWith("DAL"))
  12. .AsImplementedInterfaces();
  13. //进行注册
  14. builder.RegisterFilterProvider();
  15. //创建新容器返回值
  16. var container = builder.Build();
  17. //注册容器
  18. DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
  19. }

Autofac 依赖注入的更多相关文章

  1. 从零开始,搭建博客系统MVC5+EF6搭建框架(2),测试添加数据、集成Autofac依赖注入

    一.测试仓储层.业务层是否能实现对数据库表的操作 1.创建IsysUserInfoRepository接口来继承IBaseRepository父接口 namespace Wchl.WMBlog.IRe ...

  2. 【干货】利用MVC5+EF6搭建博客系统(二)测试添加数据、集成Autofac依赖注入

    PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.测试仓储层.业务层是否能实现对数据库表的操作 1.在52MVCBlog.IRepository程序集下创建IsysUserInf ...

  3. asp.net mvc4 简单使用Autofac依赖注入小结

    1,首先使用 NuGet下载适当的Autofac版本 文件一,Autofac.3.5.2 文件二,Autofac.Mvc4.3.1.0 1,接口类 public interface IReposito ...

  4. ASP.NETCore使用AutoFac依赖注入

    原文:ASP.NETCore使用AutoFac依赖注入 实现代码 1.新建接口类:IRepository.cs,规范各个操作类的都有那些方法,方便管理. using System; using Sys ...

  5. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  6. Autofac依赖注入

    简介 Autofac 是一款超赞的.NET IoC 容器 . 它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改 .它的实现方式是将常规的.net类当做 组件 处理. ...

  7. Autofac 依赖注入小知识

    Autofac 依赖注入小知识 控制反转/依赖注入 IOC/DI 依赖接口而不依赖于实现,是面向对象的六大设计原则(SOLID)之一.即依赖倒置原则(Dependence Inversion Prin ...

  8. WebAPI2使用AutoFac依赖注入完整解决方案。

    WebApi2上进行依赖注入,在百度里能搜到的的完整解决方案的文章少之又少,缺胳膊断腿. 和MVC5依赖注入的不同之处,并且需要注意的地方,标记在注释当中.上Global代码: namespace S ...

  9. 在MVC5和webAPI下是用Autofac依赖注入

    很多书本中都提到依赖注入,控制反转等概念,这些都是为了实现松耦合层.组件和类目的. 常见的是使用Repository类分离Controller和Model的直接联系.而为了解除Repository类和 ...

随机推荐

  1. node-sass报错解决方法

    在Vue.js中,每一个vue文件都是一个组件,在.vue文件中可以将模板,脚本,样式写在一起,便于组织整个组件.在使用template,script时,编写css样式时,都进行的特别顺利,唯独当我想 ...

  2. 【前端构建】WebPack实例与前端性能优化

    计划把微信的文章也搬一份上来. 这篇主要介绍一下我在玩Webpack过程中的心得.通过实例介绍WebPack的安装,插件使用及加载策略.感受构建工具给前端优化工作带来的便利. 壹 | Fisrt 曾几 ...

  3. 【代码笔记】iOS-中国地图

    一,效果图. 二,工程图. 三,代码. AppDelegate.m #import "AppDelegate.h" //加入头文件 #import "DrawMapVie ...

  4. Android WebView 302斗争之旅

    一.背景 越来越多的业务接入,项目内多多少少会出现几个H5页面,只是单纯的提供WebView容器接入H5页面根本满足不了需求,他们需要登录态,需要制定协议控制Native的导航栏,或者需要JsBrid ...

  5. jqgrid+bootstrap样式实践

    jqgrid+bootstrap样式实践,报错数据加载,选中,删除等功能 需要引入的样式 bootstrap.min.css ui.jqgrid.css 需要引入的JS jquery.min.js b ...

  6. 【译】Spring 4 + Hibernate 4 + Mysql + Maven集成例子(注解 + XML)

    前言 译文链接:http://websystique.com/spring/spring4-hibernate4-mysql-maven-integration-example-using-annot ...

  7. ITIS-资料集合贴

    ITIS-资料集合贴 说明:这个贴用于收集笔者能力范围内收集收藏并认为有用的资料,方便各方参考,免去到处找寻之苦,提升信息的交叉引用价值.另外,笔者就自己感悟做了部分评注,且可能尝试不断的优化分类和排 ...

  8. Oracle数据行拆分多行

    工作和学习中常常会遇到一行要分割成多行数据的情况,在此整理一下做下对比. 单行拆分 如果表数据只有一行,则可以直接在原表上直接使用connect by+正则的方法,比如: select regexp_ ...

  9. Jsoup系列学习(1)-发送get或post请求

    简介 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据. 官 ...

  10. CentOS yum 源的配置与使用

    一.yum 简介 yum,是Yellow dog Updater, Modified 的简称,是杜克大学为了提高RPM 软件包安装性而开发的一种软件包管理器.起初是由yellow dog 这一发行版的 ...