Autofac的基本使用---3、泛型类型
准备
使用的表是Teacher,创建相关的IDAL、DAL、IBLL、BLL层。
使用EF,创建一个Model层,存放edmx文件。
创建一个Infrastructure层,基础设施项目,使用泛型类型。



控制台程序的使用
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.Infrastructure.BaseObject;
using Apps.Infrastructure.IBaseInterface;
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<StudentDAL>().AsSelf().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
// 创建组件/服务注册的容器
var builder = new ContainerBuilder(); // 注册类型公开接口
builder.RegisterType<TeacherDAL>().As<ITeacherDAL>();
builder.RegisterType<TeacherBLL>().As<ITeacherBLL>();
//方式1.以泛型方式注册
builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();
builder.RegisterGeneric(typeof(DatabaseFactory<>)).As(typeof(IDatabaseFactory<>)).SingleInstance(); //方式2.以普通的方式注册
//builder.RegisterType<UnitOfWork<AutofacDBEntities>>().As<IUnitOfWork<AutofacDBEntities>>().SingleInstance();
//builder.RegisterType<DatabaseFactory<AutofacDBEntities>>().As<IDatabaseFactory<AutofacDBEntities>>().SingleInstance(); // 编译容器完成注册且准备对象解析
var container = builder.Build(); // 现在你可以使用 Autofac 解析服务. 例如,这行将执行注册的lambda表达式对于 IConfigReader 服务.
//但是我们不推荐直接操作容器,这会导致内存泄漏。
//当我们解析出一个组件时,依赖于我们定义的lifetime scope,一个新的对象实例会被创建。
using (var scope = container.BeginLifetimeScope())
{
//从容器中解析需要使用的组件
var iTeacherBLL = scope.Resolve<ITeacherBLL>();
//调用解析后的组件中的方法 List<Teacher> list = iTeacherBLL.GetList(t => t.gKey != null).ToList();
Console.WriteLine("List中的数据行:" + list.Count); //Teacher model = iTeacherBLL.GetModelByCondition(t => t.iAge == 5);
//model.dAddTime = DateTime.Now;
//iTeacherBLL.Update(); Teacher model = new Teacher();
model.gKey = Guid.NewGuid();
model.iAge = 12;
model.sName = "郭彤";
model.dAddTime = DateTime.Now;
Console.WriteLine(iTeacherBLL.Add(model));
}
#endregion Console.ReadKey();
}
}
}
(1)使用流程
a.参见Autofac管理注册类的容器实例
var builder = new ContainerBuilder();
b.下面就需要为这个容器注册它可以管理的类型
builder.RegisterType<StudentDAL>().As<IStudentDAL>();
c.注册泛型,这个地方需要把泛型进行注册,否则无法正常执行
builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();
或
builder.RegisterType<UnitOfWork<AutofacDBEntities>>().As<IUnitOfWork<AutofacDBEntities>>().SingleInstance();
d.生成具体的实例
var container = builder.Build();
e.在应用运行期间,你需要从容器生命周期域中解析出组件实例来使用它们。
using (var scope = container.BeginLifetimeScope()) { }
f.从容器中解析需要使用的组件
var iStudentBLL = scope.Resolve<IStudentBLL>();
g.调用解析出来的组件的方法
List<Student> list = iStudentBLL.GetList().ToList();
(2)中间碰到的问题。
在(1)的c.注册泛型,这个地方需要把泛型进行注册,否则无法正常执行 步骤时,
开始的注册代码是:builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>));
也就是没有带最后面的.SingleInstance();方法。
此时测试时,是能获取到数据的,
但是,当新增修改删除数据时,却无法进行。
单步调试发现,UnitOfWork中的数据库上下文对象中的实体是空的。
想起之前看到网上大神说的,UnitOfWork就是保证在操作数据时使用的是同一个状态下的数据库,以保证数据的一致性。
猜测,Autofac的配置有问题,我没有获取到同一个操作数据库的对象导致。
于是,百度相关的问题。在大佬网页:https://www.cnblogs.com/jys509/p/4649798.html
找到了这么个配置,然后在注册组件时加上这个方法,再进行测试时 新增修改数据就成功了。

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 #region 泛型类型---Teacher
private readonly ITeacherBLL _iBLL;
public HomeController(ITeacherBLL iBLL)
{
this._iBLL = iBLL;
}
public ActionResult Index()
{
List<Teacher> lstStudent = _iBLL.GetList(t => t.gKey != null).ToList(); Teacher model1 = _iBLL.GetModelByCondition(t => t.iAge == 5);
model1.dAddTime = DateTime.Now;
_iBLL.Update(); //Teacher model = new Teacher();
//model.gKey = Guid.NewGuid();
//model.iAge = 12;
//model.sName = "郭彤";
//model.dAddTime = DateTime.Now;
//_iBLL.Add(model); return View(lstStudent);
}
#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.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
}
}
}
前面两个Index.cshtml和HomeCotroller.cs只是数据的展示,所以被折叠起来。
重点在Global.asax中的配置。
(1)使用流程
自己理解
a.参见Autofac管理注册类的容器实例
var builder = new ContainerBuilder();
b.下面就需要为这个容器注册它可以管理的类型
builder.RegisterType<StudentDAL>().As<IStudentDAL>();
c.注册泛型,这个地方需要把泛型进行注册,否则无法正常执行
builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();
或
builder.RegisterType<UnitOfWork<AutofacDBEntities>>().As<IUnitOfWork<AutofacDBEntities>>().SingleInstance();
d.注册Controller,这个有两个方式。一、手动对项目中所有的Controller进行注册。二、使用Autofac的方法对程序集中所有的Controller一次性完成注册
builder.RegisterType<HomeController>().InstancePerDependency();//手动注册单个
或
builder.RegisterControllers(Assembly.GetExecutingAssembly());//自动注册全部
e.生成具体的实例
var container = builder.Build();
f.依赖关系解析.就是使用MVC的扩展 更改了MVC中的注入方式.
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
结果,运行正常。

Autofac的基本使用---3、泛型类型的更多相关文章
- Autofac 的点滴
泛型类型的注册和使用 public interface IRepository<T> where T:class { } public interface ISchoolDetailRep ...
- Autofac 组件、服务、自动装配 《第二篇》
一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...
- Autofac 依赖注入
介绍 Autofac是一款IOC框架,很轻量级性能非常高,自动注入很给力. NuGet Autofac:Autofac控制反转容器核心 Autofac.MVC5:提供IDependencyResolv ...
- [翻译] Autofac 中注册的概念
原文链接:http://docs.autofac.org/en/latest/register/registration.html 所谓注册组件,是指创建 ContainerBuilder 的实例,并 ...
- Autofac全面解析系列(版本:3.5) – [使用篇(推荐篇):1.类型注册]
前言 Autofac Autofac是一套高效的依赖注入框架. Autofac官方网站:http://autofac.org/ Autofac在Github上的开源项目:https://github. ...
- 从头开始一步一步实现EF6+Autofac+MVC5+Bootstarp极简的实现前后台ajax表格展示及分页实现
本来是想试着做一个简单OA项目玩玩的,真是不做不知道,一做吓死人,原来以为很简单的事情,但是做起来不是忘这就是忘那的,有的技术还得重新温习.所以还是得记录.免得哪天电脑挂了,就全没有了. 开始是看了园 ...
- Autofac介绍
原帖:http://www.cnblogs.com/xupng/archive/2011/07/12/2104766.html Autofac为何物?它是.NET世界里现存的几种IOC框架其中之一,传 ...
- IoC容器Autofac正篇之类型注册(四)
Autofac类型注册 类型注册简单的从字面去理解就可以了,不必复杂化,只是注册的手段比较丰富. (一)类型/泛型注册 builder.RegisterType<Class1>(); 这种 ...
- AutoFac初探
.net 4.0使用的DLL #region RegisterType注册 var builder = new ContainerBuilder(); builder.RegisterType< ...
随机推荐
- P6823 「EZEC-4」zrmpaul Loves Array
发现进行一次排序后先前的操作都无效了,所以只需做最后一次排序后的操作.翻转操作打个翻转标记,互换操作根据翻转标记即可. 时间复杂度 \(O\left(n+m\right)\). code: #incl ...
- Java基础教程——类和对象
视屏讲解:https://www.bilibili.com/video/av48272174 面向过程 VS 面向对象 面向过程:强调步骤. 面向对象:强调对象. 面向对象的特点就是:隐藏具体实现的细 ...
- Mybatis【2.3】-- Mybatis一定要使用commit才能成功修改数据么?
代码直接放在Github仓库[https://github.com/Damaer/Mybatis-Learning],mybatis-02可直接运行,就不占篇幅了. 为什么我们有时候不使用commit ...
- 编程语言输出“ Hello World ”,你真的都会了吗?
Hello World 中文意思是『你好,世界』.因为<The C Programming Language>中使用它做为第一个演示程序,非常著名,所以后来的程序员在学习编程或进行设备调试 ...
- Java多线程中的wait/notify通信模式
前言 最近在看一些JUC下的源码,更加意识到想要学好Java多线程,基础是关键,比如想要学好ReentranLock源码,就得掌握好AQS源码,而AQS源码中又有很多Java多线程经典的一些应用:再比 ...
- linux查看内存及磁盘使用情况
1.查看当前目录 命令: df -h (统一每个目录下磁盘的整体情况) 2.查看指定目录 在命令后直接放目录名,比如查看"usr"目录使用情况: 命令: df ...
- 在Centos7下docker配置自动化环境镜像(python3.7+selenium 3.11+firefox 62+geckodriver 0.21)
最近在学习Docker,准备做自动化测试代码集成的功能.如下文章的前提是已经安装好linux系统,且成功安装好Docker. 接下来我会按步骤一步一步的对自动化需要的一些环境进行安装,如果没有特别说明 ...
- 在 GitHub 玩硬件——GitHub 热点速览 Vol.49
作者:HelloGitHub-小鱼干 本周的 GitHub Trending 可以说是非常之硬核,天才少年稚晖君的 2 个硬件变装项目荣登热点榜,看完将充电宝改装为显示器的视频,搭配 HDMI-PI ...
- csv文件的写操作
import csv sumbmit_csv_path = "submit_have_valid_SGD.csv" with open(sumbmit_csv_path, &quo ...
- PR全套插件一键安装
PR全套插件一键安装,无需注册码软件也是我在别的地方搬来的,自己用着很好,决定分享出来! 我的PR版本是2019,用着没有任何问题.我没有安装其他版本PR,所以无法测试,不过应该是可以用的. 使用截图 ...