介绍

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

NuGet

Autofac:Autofac控制反转容器核心

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

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

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

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

快速预览

注册组件

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

var builder = new ContainerBuilder();

// 注册单一组件
builder.RegisterInstance(new TaskRepository())
.As<ITaskRepository>();
builder.RegisterType<TaskController>();
builder.Register(c => new LogManager(DateTime.Now))
.As<ILogger>(); // 进行扫描自动注册
builder.RegisterAssemblyTypes(myAssembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces(); var container = builder.Build();

快速依赖

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

public class TaskController
{
private ITaskRepository _repository;
private ILogger _logger;
// Autofac 可以自动查找注册值,并通过他们进行服务
public TaskController(
ITaskRepository repository,
ILogger logger)
{
this._repository = repository;
this._logger = logger;
}
}

灵活的模块系统

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

public class CarTransportModule : Module
{
public bool ObeySpeedLimit { get; set; } protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Car>().As<IVehicle>();
if (ObeySpeedLimit)
builder.RegisterType<SaneDriver>().As<IDriver>();
else
builder.RegisterType<CrazyDriver>().As<IDriver>();
}
}
<!-- 进行XML部署 -->
<autofac>
<module type="CarTransportModule">
<properties>
<property name="ObeySpeedLimit" value="true" />
</properties>
</module>
</autofac>

简单的扩展方式

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

var builder = new ContainerBuilder();

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

入门

构建应用程序

/// <summary>
/// 饮品接口
/// </summary>
public interface IWater
{
string ReturnWater();
} /// <summary>
/// 可乐
/// </summary>
public class Coke : IWater
{
public string ReturnWater()
{
return "可乐";
}
} /// <summary>
/// 牛奶
/// </summary>
public class Milk : IWater
{
public string ReturnWater()
{
return "牛奶";
}
} /// <summary>
/// 茶
/// </summary>
public class Tea : IWater
{
public string ReturnWater()
{
return "茶";
}
}

IWater

#region 人类喝水方法,各模块需Copy此方法来实现

    /// <summary>
/// 定义人类接口
/// </summary>
public interface IPeople
{
/// <summary>
/// 每个人都会喝水
/// </summary>
string DrinkWater();
} /// <summary>
/// 学生喝可乐,使用构造器注入
/// </summary>
public class Students : IPeople
{
private IWater _water; public Students(IWater water)
{
_water = water;
} public string DrinkWater()
{
return string.Format("学生都爱喝:{0}", _water.ReturnWater());
}
} /// <summary>
/// 老师喝茶,使用属性注入
/// </summary>
public class Teacher : IPeople
{
public IWater Water { get; set; } public string DrinkWater()
{
return string.Format("老师都爱喝:{0}", Water.ReturnWater());
}
} /// <summary>
/// 护士和牛奶,使用方法注入
/// </summary>
public class Nurse : IPeople
{
public IWater Water { get; set; } public string DrinkWater()
{
return string.Format("护士都爱喝:{0}", Water.ReturnWater());
}
} #endregion 喝水

IPeople

添加Autofac

只需要添加核心包 Autofac 即可

启动

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

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

Container

执行

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

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

 private static void Write()
{
using (var scope = Container.BeginLifetimeScope())
{
IPeople people = scope.Resolve<IPeople>();
Console.WriteLine(people.DrinkWater());
}
}

Write

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

注册组件

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

ContainerBuilder 中包含的

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

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

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

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

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

反射元件

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

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

class Program
{
/// <summary>
/// 存储容器
/// </summary>
private static IContainer Container { get; set; }
static void Main(string[] args)
{
if (args == null)
{ /* 为了忽略重构提醒 */ } //创建一个Builder
ContainerBuilder builder = new ContainerBuilder();
//将类进行注册,在使用反射时,会加载对应接口
builder.RegisterType<MyComponent>();
builder.RegisterType<Students>().As<IPeople>();
builder.RegisterType<Coke>().As<IWater>();
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
//会自动加载对应接口
var component = container.Resolve<MyComponent>();
//输出结果:两个参数
}
Console.Read();
}
} public class MyComponent
{
public MyComponent() { Console.WriteLine("空构造"); }
public MyComponent(IPeople people) { Console.WriteLine("一个参数"); }
public MyComponent(IPeople people, IWater water) { Console.WriteLine("两个参数"); }
}

MyComponent

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

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

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

可以修改为如下

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

Lambda表达式

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

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

builder.Register(c => new Students(c.Resolve<IWater>()));

var people = container.Resolve<Students>();
Console.WriteLine(people.DrinkWater());

泛型

Autofac支持泛型类型

public interface IListA<T>
{
void Go();
} public class ListB<T> : IListA<T>
{
public void Go()
{
Console.WriteLine(string.Format("泛型:{0}", typeof(T).Name));
}
}

Entitys

builder.RegisterGeneric(typeof(ListB<>)).As(typeof(IListA<>)).InstancePerLifetimeScope();

var list = container.Resolve<IListA<string>>();
list.Go();

RegisterGeneric

重复

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

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

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

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

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

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

使用nuget安装,Autofac。

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

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. BW知识问答汇总

    什么是sap的星型结构,能不能详细讲解一下? Cube的星型结构中SID技术的优点有哪些? 什么是BW的星型结构,与传统的星型结构的区别是什么? SAP的星型结构相对于传统的星型结构优势? Cube与 ...

  2. ListView之多种类型Item

    一.概述 一般而言,listview每个item的样式是一样的,但也有很多应用场景下不同位置的item需要不同的样式. 拿微信举例,前者的代表作是消息列表,而后者的典型则是聊天会话界面. 本文重点介绍 ...

  3. 【代码笔记】iOS-用户发布后能保存崩溃

    一,工程图. 二,代码. AppDelegate.m #import "AppDelegate.h" #import "RootViewController.h" ...

  4. 网络安全——Base64编码、MD5、SHA1-SHA512、HMAC(SHA1-SHA512)哈希

    据说今天520是个好日子,为什么我想起的是502.500.404这些?还好服务器没事! 一.Base64编码 Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之 ...

  5. git基础

    1.新的未跟踪文件 新创建的README文件没有进行任何跟踪 $ git status On branch master Untracked files: (use "git add < ...

  6. CentOS安装SVN服务器

    Step1:安装svn服务器 $ yum install subversion Step2:创建SVN版本库目录 $ mkdir /workplace/svnrepos Step3:创建版本库 $ s ...

  7. MySQL高可用方案

    高可用架构对于互联网服务基本是标配,无论是应用服务还是数据库服务都需要做到高可用.虽然互联网服务号称7*24小时不间断服务,但多多少少有一些时候服务不可用,比如某些时候网页打不开,百度不能搜索或者无法 ...

  8. 2-sql基本操作

    sql基本操作 一.Sqlplus常用命令 1.查看oracle数据库的进程 2.查看oracle数据库运行状态 3.显示实例名(数据库名) 4.用sys账户登陆到数据库 5.解锁账户scott,并登 ...

  9. 使用shell脚本实现ping对应IP所对应的人名

    #!/bin/bash a=(张三 李四 王五 赵六) ..} do . $((${i}+)) >dev/>&;then ))"号"${a[${i}]}&quo ...

  10. spring 事务回滚

    1.遇到的问题 当我们一个方法里面有多个数据库保存操作的时候,中间的数据库操作发生的错误.伪代码如下: public method() { Dao1.save(Person1); Dao1.save( ...