.Net IOC框架入门之三 Autofac
一、简介
目的
1.依赖注入的目的是为了解耦。
2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置。
3.控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
4. 微软的DependencyResolver如何创建controller
生命周期
1、InstancePerDependency
对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。
官方文档解释:Configure the component so that every dependent component or call to Resolve() gets a new, unique instance (default.)
2、InstancePerLifetimeScope
在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。
官方文档解释:Configure the component so that every dependent component or call to Resolve() within a single ILifetimeScope gets the same, shared instance. Dependent components in different lifetime scopes will get different instances.
3、InstancePerMatchingLifetimeScope
在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。
官方文档解释:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope tagged with any of the provided tags value gets the same, shared instance. Dependent components in lifetime scopes that are children of the tagged scope will share the parent's instance. If no appropriately tagged scope can be found in the hierarchy an DependencyResolutionException is thrown.
4、InstancePerOwned
在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。
官方文档解释:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope created by an owned instance gets the same, shared instance. Dependent components in lifetime scopes that are children of the owned instance scope will share the parent's instance. If no appropriate owned instance scope can be found in the hierarchy an DependencyResolutionException is thrown.
5、SingleInstance
每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。
官方文档解释:Configure the component so that every dependent component or call to Resolve() gets the same, shared instance.
6、InstancePerHttpRequest (新版autofac建议使用InstancePerRequest)
在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。
官方文档解释:Share one instance of the component within the context of a single HTTP request.
二、常用方法
三、文件配置
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
</configSections>
<autofac defaultAssembly="ConsoleApplication1">
<components>
<component type="ConsoleApplication1.SqlDAL, ConsoleApplication1" service="ConsoleApplication1.IDAL" />
</components>
</autofac>
</configuration>
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<DBManager>();
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
using (IContainer container = builder.Build())
{
DBManager manager = container.Resolve<DBManager>();
manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')");
}
四、示例
MVC5示例中实现的功能有:程序集注册、按服务注册、属性注入、泛型注入
global.cs
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles); InitDependency();
StackExchange.Profiling.EntityFramework6.MiniProfilerEF6.Initialize();
} private void InitDependency()
{
ContainerBuilder builder = new ContainerBuilder(); Type baseType = typeof(IDependency); // 自动注册当前程序集
//builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
// 注册当前程序集
Assembly assemblies = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assemblies)
.Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
.AsImplementedInterfaces().InstancePerLifetimeScope();//保证对象生命周期基于请求 //注册引用的程序集
//var assemblyList = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly => assembly.GetTypes().Any(type => type.GetInterfaces().Contains(baseType)));
//var enumerable = assemblyList as Assembly[] ?? assemblyList.ToArray();
//if (enumerable.Any())
//{
// builder.RegisterAssemblyTypes(enumerable)
// .Where(type => type.GetInterfaces().Contains(baseType))
// .AsImplementedInterfaces().InstancePerLifetimeScope();
//} //注册指定的程序集
//自动注册了IStudentService、IUserService
builder.RegisterAssemblyTypes(Assembly.Load("AppService"), Assembly.Load("AppService"))
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces(); //一、Type注册服务
builder.RegisterType<CourseService>().As<ICourseService>();
builder.RegisterType<UserService>().AsSelf();// 注入类本身,等价于.As<UserService>();
builder.RegisterType<ScoreManage>().AsImplementedInterfaces();//批量注册,等价于.As<IEnglishScoreManage>().As<IMathematicsScoreManage>(); //二、Named注册服务
//builder.RegisterType<ChineseScorePlusManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString());// 一个接口与多个类型关联
//builder.RegisterType<ChineseScoreManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString());// 一个接口与多个类型关联
//三、Keyed注册服务
builder.RegisterType<ChineseScorePlusManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus);// 一个接口与多个类型关联
builder.RegisterType<ChineseScoreManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScore);// 一个接口与多个类型关联 //泛型注册,可以通过容器返回List<T> 如:List<string>,List<int>等等
//builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope(); //生命周期
//builder.RegisterType<StudentService>().As<IStudentService>().InstancePerLifetimeScope(); //基于线程或者请求的单例..就是一个请求 或者一个线程 共用一个
//builder.RegisterType<StudentService>().As<IStudentService>().InstancePerDependency(); //服务对于每次请求都会返回单独的实例
//builder.RegisterType<StudentService>().As<IStudentService>().SingleInstance(); //单例.. 整个项目公用一个
//builder.RegisterType<StudentService>().As<IStudentService>().InstancePerRequest(); //针对MVC的,或者说是ASP.NET的..每个请求单例 builder.RegisterType<ServiceGetter>().As<IServiceGetter>();//用于一个接口与多个类型关联 builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();//属性注入,未注册将出现“没有为该对象定义无参数的构造函数。” builder.RegisterType<TestDbContext>().As<IDbContext>().InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();//泛型注入 //builder.RegisterFilterProvider(); //注入特性,特性里面要用到相关的服务
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//生成容器并提供给MVC
} protected void Application_BeginRequest()
{
if (Request.IsLocal)//这里是允许本地访问启动监控,可不写
{
MiniProfiler.Start(); }
}
protected void Application_EndRequest()
{
MiniProfiler.Stop();
}
}
控制器
public class HomeController : Controller
{ private readonly IStudentService _studentService;
private readonly ITeacherService _teacherService;
private readonly IUserService _userService; public readonly UserService UserService; private readonly IEnglishScoreManage _englishScoreManage;
private readonly IMathematicsScoreManage _mathematicsScoreManage;
private IServiceGetter getter; public ICourseService CourseService { get; set; } private readonly IRepository<Student> _studentRrepository; public HomeController(IStudentService studentService, IUserService userService, ITeacherService teacherService, UserService userService1, IMathematicsScoreManage mathematicsScoreManage, IEnglishScoreManage englishScoreManage, IServiceGetter getter, IRepository<Student> studentRrepository)
{
_studentService = studentService;
_userService = userService;
_teacherService = teacherService;
this.UserService = userService1;
_mathematicsScoreManage = mathematicsScoreManage;
_englishScoreManage = englishScoreManage;
this.getter = getter;
_studentRrepository = studentRrepository;
} public ActionResult Index()
{
var name = "";
var student = _studentRrepository.GetById("4b900c95-7aac-4ae6-a122-287763856601");
if (student != null)
{
name = student.Name;
} ViewBag.Name = _teacherService.GetName();
ViewBag.UserName1 = _userService.GetName();
ViewBag.UserName2 = UserService.GetName();
ViewBag.StudentName = _studentService.GetName() + "-" + name;
ViewBag.CourseName = CourseService.GetName(); ViewBag.EnglishScore = _englishScoreManage.GetEnglishScore();
ViewBag.MathematicsScore = _mathematicsScoreManage.GetMathematicsScore(); //ViewBag.ChineseScore = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString()).GetScore();
//ViewBag.ChineseScorePlus = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString()).GetScore(); ViewBag.ChineseScore = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScore).GetScore();
ViewBag.ChineseScorePlus = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus).GetScore(); return View();
}
}
页面
@{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<h1>ASP.NET</h1>
</div>
<div class="row">
<div class="col-md-4">
<h2>Teacher: @ViewBag.Name </h2>
<p>
CourseName: @ViewBag.CourseName
</p>
<p></p>
</div>
<div class="col-md-4">
<h2>User</h2>
<p>接口注入:@ViewBag.UserName1</p>
<p>类注入:@ViewBag.UserName2</p>
</div>
<div class="col-md-4">
<h2>Student: @ViewBag.StudentName</h2>
<p>English:@ViewBag.EnglishScore</p>
<p>Math: @ViewBag.MathematicsScore</p>
<p>Chinese: @ViewBag.ChineseScore</p>
<p>ChinesePlus:@ViewBag.ChineseScorePlus</p>
</div>
</div>
代码下载:https://gitee.com/zmsofts/XinCunShanNianDaiMa/blob/master/EntityFrameworkExtension.rar
注意:codefirst开发,先迁移后才能使用
参考文章:
https://www.cnblogs.com/struggle999/p/6986903.html
https://www.cnblogs.com/gdsblog/p/6662987.html
https://www.cnblogs.com/kissdodog/p/3611799.html
https://www.cnblogs.com/fuyujian/p/4115474.html
http://www.cnblogs.com/tiantianle/category/779544.html
.Net IOC框架入门之三 Autofac的更多相关文章
- .Net IOC框架入门之——Autofac
一.简介 Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个 目的 1.依赖注入的目的是为了解耦.2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置.3.控制反转即IoC ...
- .Net IOC框架入门之一 Unity
一.概述 IOC:英文全称:Inversion of Control,中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection). 作用:将各层的对象以松耦合的方式组织在一 ...
- .Net IOC框架入门之——Unity
一.概述 IOC:英文全称:Inversion of Control,中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection). 作用:将各层的对象以松耦合的方式组织在一 ...
- .Net IOC框架入门之二 CastleWindsor
一.简介 Castle是.net平台上的一个开源项目,为企业级开发和WEB应用程序开发提供完整的服务,用于提供IOC的解决方案.IOC被称为控制反转或者依赖注入(Dependency Injectio ...
- .Net IOC框架入门之——CastleWindsor
一.简介 Castle是.net平台上的一个开源项目,为企业级开发和WEB应用程序开发提供完整的服务,用于提供IOC的解决方案.IOC被称为控制反转或者依赖注入(Dependency Injectio ...
- .NET领域最为流行的IOC框架之一Autofac
一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也是用的Autofac. Orchad和Nopcomm ...
- IOC框架之一Autofac
.NET领域最为流行的IOC框架之一Autofac 一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也 ...
- .NET领域最为流行的IOC框架之一Autofac WebAPI2使用Autofac实现IOC属性注入完美解决方案 AutoFac容器初步
.NET领域最为流行的IOC框架之一Autofac 一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程 ...
- VS2010/MFC编程入门之三十九(文档、视图和框架:概述)
前面几节讲了菜单.工具栏和状态栏的使用,鸡啄米本节开始将为大家讲解文档.视图和框架的知识. 文档.视图和框架简介 在VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)创建的单文档工 ...
随机推荐
- Java面试准备之数据库
一.考察点 1.联结 1.1 联结的概念: 简单的说,联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结. 1.2 联结的分类 注意:联结并不代表只有使用join关键字的才算是联结,w ...
- js 对日期处理
// 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...
- 技术趋势:React vs Vue vs Angular
React.Vue 和 Angular 这两年发展状况如何?2019 年哪个技术最值得学习? 前几天 Medium 上有一位作者发表了一篇关于 React.Vue 和 Angular 技术趋势的文章( ...
- Java this与super的仇与恨
刚开始学习面向对象的时候,看到this和super觉得this就是指当前对象,super指最近的父级对象.觉得用处不大. 后来,随着学习的深入,看别人的代码越来越多,发现this和super的使用率贼 ...
- 相片后期处理,PS调出温暖的逆光美女
原图: 效果图: 后面就是开PS导图: 说明下,因为拍的时候大概知道自己的方法会让照片变暖,现场光线又很暖,所以色温要调低一些,这边是4100,其他不用变,直接转JPG调色了 1:第一步是加第一个曲线 ...
- vagrant之常用操作
基本操作: 查看版本: vagrant -v 初始化: vagrant init 启动虚拟机: vagrant up 关闭虚拟机: vagrant halt 重启虚拟机: vagrant reload ...
- python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
- 前端获取checkbox复选框的值 通过数组形式传递
html代码: <form role="form" class="select_people"> <div style="displ ...
- idea中war和war exploded的区别及修改jsp必须重新启动tomcat才能生效的问题
刚开始使用idea,发现工程每次修改JS或者是JSP页面后,并没有生效,每次修改都需要重启一次Tomcat这样的确不方便.我想Idea肯定有设置的方法,不可能有这么不方便的功能存在. 需要在Tomca ...
- luogu5316
P5316 恋恋的数学题 题目背景 恋恋是个可爱的女孩子,最近她沉迷了做数学题. 题目描述 现在恋恋正在处理的题目十分简单:现在有k \space (2\leq k\leq 4)k (2≤k≤4)个数 ...