一:

Autofac配置(在控制器中拿到IOC容器)

public class AutoFacConfig
{public static void Register(){ContainerBuilder builder = new Autofac.ContainerBuilder();//获取WebApp这个项目的Assembly程序集Assembly controllerAss = Assembly.Load("WebApp");//注册这个程序集中所有的IController接口的实现类(实现了IController接口的类即是控制器,所以这里是注册这个程序集中所有的控制器)builder.RegisterControllers(controllerAss);//当然,我们也可以这样写: 即注册当前项目中的所有控制器//builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();//注册NationalityDal类 (不需要以接口的形式保存,因为有的类是没有接口的,比如过滤器类,这里我们只需要将这个类进行注册即可(用IOC容器管理起来))builder.RegisterType<NationalityDal>()//或者builder.RegisterType(typeof(NationalityDal))//注册NationalityDal类,并将它转换成INationalityDal接口类型(即以NationalityDal类型的对象以INationalityDal接口的形式保存)builder.RegisterType<NationalityDal>().As<INationalityDal>();builder.RegisterType<PersonDal>().As<IPersonDal>();//以上两条语句是针对这个PersonDal这个类仅仅只实现了一个IPersonDal接口,和NationalityDal类接口仅仅实现了一个INationalityDal接口的写法//那假如PersonDal类实现了多个接口,那我们就可以这样写(假如这个PersonDal实现了5个接口,当我们需要这个5个接口的实现类的时候,都可以返回这PersonDal类的实例对象)builder.RegisterType<PersonDal>().AsImplementedInterfaces();//第四步:创建一个真正的AutoFac的工作容器  IContainer container = builder.Build();DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//----------------完//有时候我们需要在控制器中使用这个container容器来拿某个接口的实现类对象那我们怎么做呢?有两种方式://第一种://我们可以将这个container工作容器类存到缓存中,然后再控制器中通过调用获取缓存的方式拿到这个工作容器类//拿到这个工作容器类后,可以做一下操作,获取这个接口的实现类对象CacheHelper.SetCache("aotufac", container);//第二种://我们可以在控制器,或者其他地方这样写,这样就拿到了INationalityDal接口的实现类对象了var natDal = DependencyResolver.Current.GetService<INationalityDal>();//如果一个类没有接口,(只是对它进行了注册,并没有以接口的形式保存)GetService泛型参数就直接写类名即可(不一定非得是接口)var natDai = DependencyResolver.Current.GetService<NationalityDal>();}
}

既然我吧Autofac的工作容器存放到缓存中了,那我们就可以通过缓存拿到这个Autofac工作容器类

namespace WebApp.Controllers
{using Autofac;using BF.IDAL.EntityIDal;using System.Data.Entity;using WebApp.Filters;// 如果要在IQueryable接口中使用Include就如要引入它public class HomeController : Controller{public ActionResult Index(){//从缓存中获取Autofac工作容器IContainer container = CacheHelper.GetCache("autofac") as IContainer;//获取IPersonDal接口的实现类对象(假如IPersonDal接口有5个实现类,这种写法,仅仅是返回其中一个实现类的对象,具体不知道返回的是那个实现类的对象,它应该是通过Autofac的工作机制来确定返回哪个实现类对象)IPersonDal perdal = container.Resolve<IPersonDal>();//假如IPersonDal接口有5个实现类,那我们可通过以下写法获取这个5个实现类的对象集合IEnumerable<IPersonDal> persDal = container.Resolve<IEnumerable<IPersonDal>>();foreach (IPersonDal pd in persDal){//遍历IPersonDal接口的5个实现类对象。}var ninfo = perdal.GetNationality();//调用IPersonDal接口中的GetNationality()方法//调用IPersonDal接口的GetList()方法var pList = perdal.GetList().Include("Nationality").ToList();return View();}}
}

二:属性自动注入

PropertiesAutowired()方法

在Autofac配置中,我们对在创建类的实例对象,并以接口的形式保存。

builder.RegisterType<PersonDal>().AsImplementedInterfaces()

我们可以在后面加上这样一个PropertiesAutowired()方法

这个方法表示:如果一个实现类中定义了其他类型的接口属性,,它会自动给属性进行“注入”

 builder.RegisterType<PersonDal>().AsImplementedInterfaces().PropertiesAutowired();

使用:在业务逻辑层,在数据层,在控制器中均可使用。

Autofac配置

public class AutoFacConfig
{public static void Register(){ContainerBuilder builder = new Autofac.ContainerBuilder();//Assembly controllerAss = Assembly.Load("WebApp");//builder.RegisterControllers(controllerAss);//这段可以该用以下这一段代码替换//把当前程序集中的Conntroller都注册builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();//把当前程序集中的所有非抽象类型的ActionFilterAttribute都注册(这样我们在所有ActionFilterAttribute及子类中都可以使用属性注入)//前提:注册这个过滤的时候,这个过滤器的对象不能直接new出来,而是要去IOC容器中得到这个过滤类的对象。//例如:需要这样注册过滤:filters.Add(DependencyResolver.Current.GetService<CheckLoginAttribute>());builder.RegisterFilterProvider();builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly).Where(r => typeof(ActionFilterAttribute).IsAssignableFrom(r) && !r.IsAbstract).PropertiesAutowired();//注册NationalityDal类,并将它转换成INationalityDal接口类型(即以NationalityDal类型的对象以INationalityDal接口的形式保存) builder.RegisterType<NationalityDal>().As<INationalityDal>();builder.RegisterType<PersonDal>().As<IPersonDal>();//那假如PersonDal类实现了很多个接口,那我们也可以这样写//builder.RegisterType<PersonDal>().AsImplementedInterfaces()//这样写的好处是:假如这个PersonDal实现了5个接口,只要我们需要这个5个接口的实现类,都可以返回这PersonDal类的实例对象//PropertiesAutowired()表示如果一个实现类中定义了其他类型的接口属性,它会自动给属性进行“注入”builder.RegisterType<PersonDal>().AsImplementedInterfaces().PropertiesAutowired();//其实我们还可以在.PropertiesAutowired()方法后面在进行一些策略的配置://.InstancePerDependency();表示每次请求Resovle都返回一个新的对象//.SingleInstance();表示每次请求都返回同一个对象(单例),但是实现类必须是无状态的,即实现类没有成员变量(属性也不行,因为属性是由成员变量组成的),只能单纯的方法。//.InstancePerRequest(); 这个是Asp.net MVC专用,每个请求一次,在当前的http请求范围之内返回同一个对象.它的意思就是:在一个嵌套语句块中,只会返回一个实例,例如一个for循环中,在for循环中通过autofac容器获取实例对象,那么通过这种方式,它就返回同一个对象给你;详情请参考:https://www.cnblogs.com/stulzq/p/8547277.html//对一个程序集中的类进行注册(管理)Assembly repositoryAss = Assembly.Load("ZKHKCMS.Repositorys");Type[] rtypes = repositoryAss.GetTypes();builder.RegisterTypes(rtypes).AsImplementedInterfaces().PropertiesAutowired();//创建一个真正的AutoFac的工作容器  IContainer container = builder.Build();DependencyResolver.SetResolver(new AutofacDependencyResolver(container));}
}

在过滤器中使用属性注入(特别注意过滤器的注册,过滤器对象最好不要直接new,而是去IOC容器中拿,否则不能直接在过滤器中使用属性注入)

namespace WebApp.Filters
{public class CheckLoginAttribute : ActionFilterAttribute{//这里会自动对INationalityDal属性进行注入(前提,需要在控制器类或者方法上打上这个[CheckLogin]特性标签的形式进入到这个特性方法中,如果不想打标签请看下面第二段代码)public INationalityDal nat { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext){var natList = nat.GetList().ToList();}}
}

注意,如果这里在控制器中对属性进行注入,如果不想在控制器上打[CheckLogin]这个标签,就需要换种形式注册这个过滤器

namespace MvcApp.App_Start
{public class FilterConfig{public static void RegisterGlobalFilters(GlobalFilterCollection filters){filters.Add(new HandleErrorAttribute());//注册过滤器//注意:这里别使用filters.Add(new CheckLoginAttribute())这种形式来注册过滤器,否则不能直接在过滤器中使用属性注入//因为一个对象必须是由IOC容器创建出来的,IOC容器才会自动帮我们注入filters.Add(DependencyResolver.Current.GetService<CheckLoginAttribute>()); //注册过滤器,这个过滤器类对象必须得从IOC容器中得到}}
}

在DAL层中使用属性注入

namespace BF.DAL.EntityDal
{public class PersonDal : BaseDal<Person>, IPersonDal{//如果加了这个PropertiesAutowired()方法方法,这里会对INationalityDal接口注入实现类对象//但是这样有个前提,那就是PersonDal类是被Autofac工作容器类所管理的类public INationalityDal natDal { get; set; }//在PersonDal类中定义一个接口类属性(会自动进行注入)public Nationality GetNationality(){//这里可以拿到这个INationalityDal接口的实现类对象进行操作var nat = natDal.GetList().FirstOrDefault();return nat;}}
}

在控制器中使用属性注入

namespace WebApp.Controllers
{[CheckLogin]public class HomeController : Controller{//IPersonDal属性会被自动进行注入public IPersonDal perDal { get; set; }public ActionResult Index(){var list = perDal.GetList(); //调用成功return View();}}
}

解释下在注释里面说的实现类是什么意思:

例如:IPersonDal perdal = container.Resolve<IPersonDal>(); 这段代码。 Autofac工作容器的Resolve泛型方法获取IPersonDal接口的实现类对象 即获取PersonDal 类的对象

在Autofac配置中有这样一段代码:

builder.RegisterType<PersonDal>().AsImplementedInterfaces()

这段代码就表示注册(创建)PersonDal类的实例对象以接口的形式保存在Autofac的工作容器中。实际上PersonDal类就已经被Autofac管理起来了。

-------------------------------下面提供下项目的数据层

IDAL

IBaseDal<T>

namespace BF.IDAL
{public interface IBaseDal<T> where T : class{/// <summary>/// 获取数据集合/// </summary>/// <returns></returns>IQueryable<T> GetList();}
}

IPersonDal

namespace BF.IDAL.EntityIDal
{public interface IPersonDal: IBaseDal<Person>{}
}

DAL

baseDal<T>

namespace BF.DAL
{public class BaseDal<T> : IBaseDal<T> where T : class{BFDbContext db = new BFDbContext();/// <summary>/// 获取数据集合/// </summary>/// <returns></returns>public IQueryable<T> GetList(){return db.Set<T>();}}
}

PersonDal

namespace BF.DAL.EntityDal
{public class PersonDal : BaseDal<Person>, IPersonDal{//如果加了这个PropertiesAutowired()方法方法,这里会对INationalityDal接口注入实现类对象//但是这样有个前提,那就是PersonDal类是被Autofac工作容器类所管理的类对象public INationalityDal natDal { get; set; }//在PersonDal类中定义一个接口类属性(会自动进行注入)public Nationality GetNationality(){//这里可以拿到这个INationalityDal接口的实现类对象进行操作var nat = natDal.GetList().FirstOrDefault();return nat;}}
}

在一些单独的线程中通过Autofac容器来获取对象

例如:在Quartz定时框架中使用Autofac来获取接口的实例对象

如果在Quartz等单独的线程中,无法通过DependencyResolver.Current.GetService<ICityService>()获取对象,就要通过下面的方式来获取接口的实例对象

namespace WebApp
{using Quartz;using Autofac;using Autofac.Integration.Mvc;using BF.IDAL.EntityIDal;public class MyQuartz : IJob{public void Execute(IJobExecutionContext context){var container = AutofacDependencyResolver.Current.ApplicationContainer;//获取Autofac工作容器类对象using (container.BeginLifetimeScope()){//注意:这里使用Resolve需要手动using Autofac;var perdal = container.Resolve<IPersonDal>(); //获取IPersonDal接口的实现类对象var a = perdal.GetList();}}}
}

Autofac学习之三种生命周期:

  1. InstancePerLifetimeScope:每次都会返回一个新的实例,并且这是默认的生命周期
  2. SingleInstance :单例,所有服务请求都将会返回同一个实例。
  3. InstancePerDependency:在一个嵌套语句块中,只会返回一个实例。

关于InstancePerDependency详解:即在解决每个生命周期实例作用域组件时,每个嵌套作用域将获得一个实例(例如,每个工作单元)

using(var scope1 = container.BeginLifetimeScope())
{for(var i = 0; i < 100; i++){// 每次从这里解析它// 你会得到相同的实例。var w1 = scope1.Resolve<Worker>();}
}using(var scope2 = container.BeginLifetimeScope())
{for(var i = 0; i < 100; i++){//每次从这里解析它//每次解析都会得到一个同样的实例,但是这个示例和上面的循环的实例不是同一个var w2 = scope2.Resolve<Worker>();}
}

Autofac深入讲解相关推荐

  1. Asp.net MVC 仿照博客园的简单网站首页 列表设计

    本来我打算采用ajax提交请求,异步的请求获取数据,但是我发现如果这样的话就会拖慢开发的进度,拖长时间.所以在这篇博客中仿照首页的列表设计其实和左侧列表网站分类采用了同样的方式,通过局部视图的方式呈现 ...

  2. .NET Core开发实战(第7课:用Autofac增强容器能力)--学习笔记(下)

    07 | 用Autofac增强容器能力:引入面向切面编程(AOP)的能力 如何获取没有命名的服务呢? // 获取没有命名的服务,把 namd 去掉即可 var servicenamed = this. ...

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

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

  4. Ioc容器Autofac介绍

    Autofac是轻量级的开源Ioc容器,在这里可以下载http://code.google.com/p/autofac/.如果你用过其他的Ioc容器,那么学习Autofac使用也会比较容易,下面将通过 ...

  5. .net core3.1 下由Autofac接管IOC

    我们都知道,.net core天生自带IOC容器,但是他的功能其实并不强大,而且有坑:在构造注入的时候,他默认找参数最少的构造函数. 这里,我讲解如何使用Autofac去接管IOC,至于为什么要选Au ...

  6. 浅析ASP.NET应用Autofac获取页面服务

    Autofac是应用于.Net平台的依赖注入(DI,Dependency Injection)容器,具有贴近.契合C#语言的特点.随着应用系统的日益庞大与复杂,使用Autofac容器来管理组件之间的关 ...

  7. AutoFac使用笔记以及操作技巧(保姆级操作)

    背景: AutoFac是解决项目耦合的比较不错的框架.是构建大型项目上的一把利器.这里就记录一下安装以及使用的过程以及心得.方便新手尽快上手 使用过程: 1.安装: 2.引入命名空间: 3.两个部分, ...

  8. ABP 详解系列4:ABP框架的基础配置及依赖注入讲解

    ABP框架的基础配置及依赖注入讲解 这篇文章主要介绍了ABP框架的基础配置及依赖注入讲解,是ABP框架上手使用的基本,要的朋友可以参考下 配置ABP 配置是通过在自己模块的PreInitialize方 ...

  9. 【愚公系列】2023年03月 MES生产制造执行系统-001.Autofac的使用

    文章目录 前言 一.Autofac的使用 1.安装包 2.服务注入 3.AddModule扩展方法详解 3.1 AppSetting.Init 3.1.1 数据库字符串加/解密 3.2 Autofac ...

最新文章

  1. 98后常春藤学霸林之秋,一作拿下CVPR最佳论文提名,首次挑战图片翻转不变性假设...
  2. 聊聊接口优化的几个方法
  3. MySQL 和 Innobackup 不定期卡住的秘密
  4. DotNetSpeech.dll的使用
  5. 直接访问静态图片_详解nginx和tomcat访问图片和静态页面的配置方法
  6. 从介质部署额外域控制器
  7. 图像降噪算法——维纳滤波
  8. centos 修改语言、时区
  9. C++细节系列(零):零散记录
  10. python客户端服务器_Python客户端和服务器ch
  11. 商业智能BI如何推进制造业转型
  12. Unity_游戏源码
  13. 202206-2 寻宝大冒险
  14. gdata_YouTube GData API和Android
  15. UGC、元宇宙概念、与迷你世界玩法
  16. Linux内核升级(降级)
  17. CSDN大神多,在这里驻扎一下,沾沾神气
  18. 虫口模型 matlab,虫口模型的研究与教学设计.PDF
  19. Ubuntu20.04台式机网线连接Win10笔记本上网(亲测)
  20. 如何修改springboot通过maven下载的jar包源码

热门文章

  1. matlab画三维曲面有范围,matlab画三维曲面
  2. 域控知识与安全01:域控知识基础
  3. 1.dom4j 解析xml
  4. Selenium UnreachableBrowserException异常处理方案
  5. 著书立说,就现在——IT东方会T-Book出书专场第二期圆满举办
  6. 【English】十大词性之感叹词(感叹句)
  7. 深度学习——学习率衰减(learning rate decay)
  8. LeetCode | 575. Distribute Candies
  9. 理解矩阵和特征向量的本质
  10. zip解压文件 删除文件和文件目录