Autofac的基本使用---目录

准备

使用的表是Student,创建相关的IDAL、DAL、IBLL、BLL层。

使用EF,创建一个Model层,存放edmx文件。

控制台程序的使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Apps.BLL;
using Apps.DAL;
using Apps.IBLL;
using Apps.IDAL;
using Apps.Model;
using Autofac; namespace Apps.Con
{
class Program
{
static void Main(string[] args)
{
#region 普通类型---Student
// 创建组件/服务注册的容器
var builder = new ContainerBuilder(); // 注册类型公开接口
builder.RegisterType<StudentDAL>().As<IStudentDAL>();
builder.RegisterType<StudentBLL>().As<IStudentBLL>(); // 编译容器完成注册且准备对象解析
var container = builder.Build(); // 现在你可以使用 Autofac 解析服务. 例如,这行将执行注册的lambda表达式对于 IConfigReader 服务.
//但是我们不推荐直接操作容器,这会导致内存泄漏。
//当我们解析出一个组件时,依赖于我们定义的lifetime scope,一个新的对象实例会被创建。
using (var scope = container.BeginLifetimeScope())
{
//从容器中解析需要使用的组件
var iStudentBLL = scope.Resolve<IStudentBLL>();
//调用解析后的组件中的方法
List<Student> list = iStudentBLL.GetList().ToList(); Console.WriteLine("List中的数据行:"+list.Count);
}
#endregion #region 泛型类型---Teacher #endregion Console.ReadKey();
}
}
}

(1)使用流程

专业介绍:

参见:https://www.cnblogs.com/mantgh/p/5106149.html

将Autofac集成进你的应用的基本模式:

  • 在脑海中构造基于控制反转(IoC)的应用程序架构
  • 添加Autofac引用.
  • 在应用启动配置流程...
  • 创建一个 ContainerBuilder.
  • 注册组件(components).
  • build定义的ContainerBuilder生成Autofac容器,并存储它以供后续使用.
  • 在程序运行时...
  • 从Autofac容器(container)创建生命周期域(lifetime scope).
  • 使用生命周期域来解析出组件实例.

自己理解:

a.参见Autofac管理注册类的容器实例

  var builder = new ContainerBuilder();

b.下面就需要为这个容器注册它可以管理的类型

  builder.RegisterType<StudentDAL>().As<IStudentDAL>();

c.生成具体的实例

  var container = builder.Build();

d.在应用运行期间,你需要从容器生命周期域中解析出组件实例来使用它们。

  using (var scope = container.BeginLifetimeScope())  {  }

e.从容器中解析需要使用的组件

  var iStudentBLL = scope.Resolve<IStudentBLL>();

f.调用解析出来的组件的方法

  List<Student> list = iStudentBLL.GetList().ToList();

MVC中的使用

@model List<Apps.Model.Teacher>
@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<table>
<tr>
<th style="width: 400px">主键
</th>
<th style="width: 80px">姓名
</th>
<th style="width: 40px">年龄
</th>
<th style="width: 400px">创建时间
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td style="text-align:center">
@Html.DisplayFor(modelItem => item.gKey)
</td>
<td style="text-align:center">
@Html.DisplayFor(modelItem => item.sName)
</td>
<td style="text-align:center">
@Html.DisplayFor(modelItem => item.iAge)
</td>
<td style="text-align:center">
@Html.DisplayFor(modelItem => item.dAddTime)
</td>
</tr>
}
</table>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Apps.IBLL;
using Apps.Model;
using Autofac;
using Autofac.Core; namespace Apps.Web.Controllers
{
public class HomeController : Controller
{
#region 普通类型---Student
private readonly IStudentBLL _iBLL;
public HomeController(IStudentBLL iBLL)
{
this._iBLL = iBLL;
}
public ActionResult Index()
{
List<Student> lstStudent = _iBLL.GetList().ToList(); //为了视图不要重写,将Student类赋值给Teacher类。两个类的字段完全一样
List<Teacher> lstTeacher = new List<Teacher>();
foreach (Student item in lstStudent)
{
Teacher model = new Teacher();
model.gKey = item.gKey;
model.sName = item.sName;
model.iAge = item.iAge;
model.dAddTime = item.dAddTime;
lstTeacher.Add(model);
} return View(lstTeacher);
}
#endregion #region 将容器保存在Application中---Student
//private IStudentBLL _iBLL;
//public ActionResult Index()
//{
// if (_iBLL == null)
// {
// object oContainer = System.Web.HttpContext.Current.Application["container"];
// if (oContainer != null && oContainer != "")
// {
// IContainer ioc = (IContainer)oContainer;
// //当我们解析出一个组件时,依赖于我们定义的lifetime scope,一个新的对象实例会被创建。
// using (var scope = ioc.BeginLifetimeScope())
// {
// //从容器中解析需要使用的组件
// _iBLL = scope.Resolve<IStudentBLL>();
// //调用解析后的组件中的方法
// List<Student> list = _iBLL.GetList().ToList(); // Console.WriteLine("List中的数据行:" + list.Count);
// }
// }
// else
// {
// throw new Exception("IOC容器初始化发生错误!");
// }
// }
// List<Student> lstStudent = _iBLL.GetList().ToList(); // //为了视图不要重写,将Student类赋值给Teacher类。两个类的字段完全一样
// List<Teacher> lstTeacher = new List<Teacher>();
// foreach (Student item in lstStudent)
// {
// Teacher model = new Teacher();
// model.gKey = item.gKey;
// model.sName = item.sName;
// model.iAge = item.iAge;
// model.dAddTime = item.dAddTime;
// lstTeacher.Add(model);
// } // return View(lstTeacher);
//}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Apps.BLL;
using Apps.DAL;
using Apps.IBLL;
using Apps.IDAL;
using Apps.Web.Controllers;
using Autofac;
using Autofac.Integration.Mvc; namespace Apps.Web
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes); #region 普通类型---Student
// 创建组件/服务注册的容器
var builder = new ContainerBuilder(); // 注册类型公开接口
builder.RegisterType<StudentDAL>().As<IStudentDAL>();
builder.RegisterType<StudentBLL>().As<IStudentBLL>();        //方式1:单个Controller的注册(项目中有多少个Controller就要写多少次)
builder.RegisterType<HomeController>().InstancePerDependency();
//方式2:使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册
//builder.RegisterControllers(Assembly.GetExecutingAssembly()); //生成具体的实例
var container = builder.Build();
//下面就是使用MVC的扩展 更改了MVC中的注入方式.
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
#endregion #region 泛型类型---Teacher #endregion
}
}
}

前面两个Index.cshtml和HomeCotroller.cs只是数据的展示,所以被折叠起来。

重点在Global.asax中的配置。

(1)使用流程

自己理解

a.参见Autofac管理注册类的容器实例

  var builder = new ContainerBuilder();

b.下面就需要为这个容器注册它可以管理的类型

  builder.RegisterType<StudentDAL>().As<IStudentDAL>();

c.注册Controller,这个有两个方式。一、手动对项目中所有的Controller进行注册。二、使用Autofac的方法对程序集中所有的Controller一次性完成注册

  builder.RegisterType<HomeController>().InstancePerDependency();//手动注册单个

  builder.RegisterControllers(Assembly.GetExecutingAssembly());//自动注册全部

d.生成具体的实例

  var container = builder.Build();

e.依赖关系解析.就是使用MVC的扩展 更改了MVC中的注入方式.

  DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

存在的疑问

(1)MVC使用中多的步骤一,注册Controller控制器。且不注册的话,运行时会提示。这个步骤是做什么的?

(2)MVC中多的步骤二,依赖关系解析.添加了该步骤后,Controller中的组件配置为构造或属性注入(如下图配置为构造注入),

在程序运行时,申明的组件已经被实例化了。

省略了控制台程序中,去手动解析需要使用的组件

(3)MVC中免去了手动解析的步骤,那么在ASP.NET Webform项目中应该怎么使用呢?

公司的ASP.NET Webform项目中,使用的是Unity进行依赖注入。

使用步骤:

a.在Application_Start方法中进行注册

  UnityRegister.Register(Application);

b.详细代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity; namespace BF.Web.App_Code
{
public class UnityRegister
{
public static void Register(HttpApplicationState Application)
{
IUnityContainer unityContainer = new UnityContainer();
//注册关系
unityContainer.RegisterType<IIcCardLogBLL, IcCardLogBLL>(new HttpContextLifetimeManager<IIcCardLogBLL>());
unityContainer.RegisterType<IIcCardLogDAL, IcCardLogDAL>(new HttpContextLifetimeManager<IIcCardLogDAL>());
//将配置信息保存到Application
Application.Add("UnityContainer", unityContainer);
}
}
}

c.使用时

  IIcCardLogBLL iIcCardLogBLL= IOCFactory.GetIOCResolve<IIcCardLogBLL>();

d.详细代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using System.Web;
using System.Configuration;
using Microsoft.Practices.Unity.Configuration; namespace BF.UnityFactory
{
public static class IOCFactory
{ public static T GetIOCResolve<T>()
{
if (HttpContext.Current.Application["UnityContainer"] != null && HttpContext.Current.Application["UnityContainer"] != "")
{
//从Application获取容器
IUnityContainer ioc = HttpContext.Current.Application["UnityContainer"] as UnityContainer;
//从容器中解析组件
return ioc.Resolve<T>();
}
else
{
throw new Exception("IOC容器初始化发生错误!");
}
}
}
}

(4)在MVC中尝试上面的方法,修改HomeController 和Application_Start的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Apps.BLL;
using Apps.DAL;
using Apps.IBLL;
using Apps.IDAL;
using Apps.Infrastructure.BaseObject;
using Apps.Infrastructure.IBaseInterface;
using Apps.Web.Controllers;
using Autofac;
using Autofac.Integration.Mvc; namespace Apps.Web
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes); #region 普通类型---Student
//// 创建组件/服务注册的容器
//var builder = new ContainerBuilder(); //// 注册类型公开接口
//builder.RegisterType<StudentDAL>().As<IStudentDAL>();
//builder.RegisterType<StudentBLL>().As<IStudentBLL>(); ////方式1:单个Controller的注册(项目中有多少个Controller就要写多少次)
//builder.RegisterType<HomeController>().InstancePerDependency();
////方式2:使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册
////builder.RegisterControllers(Assembly.GetExecutingAssembly()); ////生成具体的实例
//var container = builder.Build();
////下面就是使用MVC的扩展 更改了MVC中的注入方式.
//DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
#endregion #region 将容器保存在Application中---Student
// 创建组件/服务注册的容器
var builder = new ContainerBuilder(); // 注册类型公开接口
builder.RegisterType<StudentDAL>().As<IStudentDAL>();
builder.RegisterType<StudentBLL>().As<IStudentBLL>(); //方式1:单个Controller的注册(项目中有多少个Controller就要写多少次)
//builder.RegisterType<HomeController>().InstancePerDependency();
//方式2:使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册
//builder.RegisterControllers(Assembly.GetExecutingAssembly()); //生成具体的实例
var container = builder.Build();
//下面就是使用MVC的扩展 更改了MVC中的注入方式.
//DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); Application.Add("container", container);
#endregion #region 泛型类型---Teacher
//// 创建组件/服务注册的容器
//var builder = new ContainerBuilder(); //// 注册类型公开接口 //builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();
//builder.RegisterGeneric(typeof(DatabaseFactory<>)).As(typeof(IDatabaseFactory<>)).SingleInstance(); //builder.RegisterType<TeacherBLL>().As<ITeacherBLL>();
//builder.RegisterType<TeacherDAL>().As<ITeacherDAL>(); ////方式1:单个Controller的注册(项目中有多少个Controller就要写多少次)
////builder.RegisterType<HomeController>().InstancePerDependency();
////方式2:使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册
//builder.RegisterControllers(Assembly.GetExecutingAssembly()); ////生成具体的实例
//var container = builder.Build();
////下面就是使用MVC的扩展 更改了MVC中的注入方式.
//DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
#endregion
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Apps.IBLL;
using Apps.Model;
using Autofac;
using Autofac.Core; namespace Apps.Web.Controllers
{
public class HomeController : Controller
{
#region 普通类型---Student
//private readonly IStudentBLL _iBLL;
//public HomeController(IStudentBLL iBLL)
//{
// this._iBLL = iBLL;
//}
//public ActionResult Index()
//{
// List<Student> lstStudent = _iBLL.GetList().ToList(); // //为了视图不要重写,将Student类赋值给Teacher类。两个类的字段完全一样
// List<Teacher> lstTeacher = new List<Teacher>();
// foreach (Student item in lstStudent)
// {
// Teacher model = new Teacher();
// model.gKey = item.gKey;
// model.sName = item.sName;
// model.iAge = item.iAge;
// model.dAddTime = item.dAddTime;
// lstTeacher.Add(model);
// } // return View(lstTeacher);
//}
#endregion #region 将容器保存在Application中---Student
private IStudentBLL _iBLL;
public ActionResult Index()
{
if (_iBLL == null)
{
object oContainer = System.Web.HttpContext.Current.Application["container"];
if (oContainer != null && oContainer != "")
{
IContainer ioc = (IContainer)oContainer;
//当我们解析出一个组件时,依赖于我们定义的lifetime scope,一个新的对象实例会被创建。
using (var scope = ioc.BeginLifetimeScope())
{
//从容器中解析需要使用的组件
_iBLL = scope.Resolve<IStudentBLL>();
//调用解析后的组件中的方法
List<Student> list = _iBLL.GetList().ToList(); Console.WriteLine("List中的数据行:" + list.Count);
}
}
else
{
throw new Exception("IOC容器初始化发生错误!");
}
}
List<Student> lstStudent = _iBLL.GetList().ToList(); //为了视图不要重写,将Student类赋值给Teacher类。两个类的字段完全一样
List<Teacher> lstTeacher = new List<Teacher>();
foreach (Student item in lstStudent)
{
Teacher model = new Teacher();
model.gKey = item.gKey;
model.sName = item.sName;
model.iAge = item.iAge;
model.dAddTime = item.dAddTime;
lstTeacher.Add(model);
} return View(lstTeacher);
}
#endregion
}
}

同样能获取到数据。

注意:Application_Start中没有进行Controller的注册和依赖关系解析这两步操作。

但是,个人感觉这样处理不是太合适。

第一,将数据保存在Application中,是不是存在数据丢失和安全的问题。

第二,在使用时,还是需要调用公用去解析组件。

总之,不如使用上面MVC自带的方法处理的方便和简洁。

Autofac的基本使用---2、普通类型的更多相关文章

  1. IoC容器Autofac正篇之类型关联(服务暴露)(七)

    类型关联 类型关联就是将类挂载到接口(一个或多个)上去,以方便外部以统一的方式进行调用(看下例). 一.As关联 我们在进行手动关联时,基本都是使用As进行关联的. class Program { s ...

  2. IoC容器Autofac正篇之类型关联(服务暴露)(八)

    类型关联  类型关联就是将类挂载到接口(一个或多个)上去,以方便外部以统一的方式进行调用(看下例). 一.As关联 我们在进行手动关联时,基本都是使用As进行关联的. 1 2 3 4 5 6 7 8 ...

  3. Autofac之类型关联

    前面的学习一直使用的是直接注册类型并不是Autofac已经依赖注入的主要使用方式,最佳的依赖注入与Autofac的使用方式,都是要结合面向接口(抽象)编程的概念的.推崇的是依赖于抽象而不是具体 pub ...

  4. Autofac 的属性注入,IOC的坑

    Autofac 是一款优秀的IOC的开源工具,完美的适配.Net特性,但是有时候我们想通过属性注入的方式来获取我们注入的对象,对不起,有时候你还真是获取不到,这因为什么呢? 1.你对Autofac 不 ...

  5. Autofac 组件、服务、自动装配 《第二篇》

    一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...

  6. [翻译] Autofac 入门文档

    原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: 用控制反转(IoC)的思想 ...

  7. AutoFac使用~IOC容器(DIP,IOC,DI)

    #cnblogs_post_body h1 { background-color: #A5A5A5; color: white; padding: 5px } Autofac一款IOC容器,据说比Sp ...

  8. Autofac 入门

    Autofac 入门文档 原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: ...

  9. Autofac 组件、服务、自动装配(2)

    一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...

  10. Autofac之自动装配

    从容器中的可用服务中选择一个构造函数来创造对象,这个过程叫做自动装配.这个过程是通过反射实现的 默认 思考这么一个问题,如果注册类型中存在多个构造函数,那么Autofac会选择哪一个来创建类型的实例 ...

随机推荐

  1. python办公入门4:xlrd操作excel行

    操作excel行 1 #通过索引获取操作行 2 sheet=data.sheet_by_index(0) 3 #获取当前sheet下的有效行数 4 print(sheet.nrows) 5 #获取某一 ...

  2. Java基础教程——Object类

    Object类 Object类是Java所有类类型的父类(或者说祖先类更合适) <Thinking in Java(Java编程思想)>的第一章名字就叫"everything i ...

  3. Goland 2020.2.x 激活码永久破解教程 (最新Goland激活码!2020.11.26亲测可用!)

    在2020.11.26 Goland的用户们又迎来了一次更新,这就导致很多软件打开时候就提示Goland激活码已经失效,码小辫第一时间给各位分享了关于最新Goland激活破解教程! goland已经更 ...

  4. 20190627_解决ADB的device offline问题的两种方法

    故障现象: error: device offline 故障解决: 第一种方法: C:\Users\WXY\Desktop\XY\adb>adb nodaemon server cannot b ...

  5. RabbitMQ Go客户端教程5——topic

    本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第五篇--topic. 这些教程涵盖了使用RabbitMQ创建消息传递 ...

  6. 第7.20节 案例详解:Python抽象类之真实子类

    第7.20节 案例详解:Python抽象类之真实子类 上节介绍了Python抽象基类相关概念,并介绍了抽象基类实现真实子类的步骤和语法,本节结合一个案例进一步详细介绍. 一.    案例说明 本节定义 ...

  7. PyQt开发案例:结合QDial实现的QStackedWidget堆叠窗口程序例子及完整代码

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.案例说明 本案例是老猿在学习QStackedWidget中的一个测试案例,该案例使用QStack ...

  8. 被老猿误解的Python匿名函数lambda

    在<第2.3节 Python运算符大全>老猿这样描述lambda:"上述运算符中有个lambda,这是个lambda就是用来定义一个匿名函数的.老猿认为用处不大,具体内容大家可以 ...

  9. 转:使用DOS命令chcp查看windows操作系统的默认编码以及编码和语言的对应关系

    代码页是字符集编码的别名,也有人称"内码表".早期,代码页是IBM称呼电脑BIOS本身支持的字符集编码的名称.当时通用的操作系统都是命令行界面系统,这些操作系统直接使用BIOS供应 ...

  10. QQFishing QQ钓鱼站点搭建

    答:为什么要写这个代码? 当然不是做黑产去盗别人扣扣,也没有啥查看别人隐私信息的癖好,搭建该站点的适用对象为->使用社会工程学定向钓鱼攻击的安全渗透人员 另外管理员界面后端写的很丑+很烂,除了我 ...