IOC-Autofac 痛定思痛。 2022-05-31 12:37 192阅读 0赞 Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高。 官方网站[http://autofac.org/][http_autofac.org] 源码下载地址[https://github.com/autofac/Autofac][https_github.com_autofac_Autofac] **控制反转(IoC/Inverse Of Control):** 调用者不再创建被调用者的实例,由autofac框架实现(容器创建)所以称为控制反转。 **依赖注入(DI/Dependence injection) :** 容器创建好实例后再注入调用者称为依赖注入。 **安装Autofac** ![这里写图片描述][70] 1、InstancePerDependency 对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。 2、InstancePerLifetimeScope 在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。 3、InstancePerMatchingLifetimeScope 在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。 4、InstancePerOwned 在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。 5、SingleInstance 每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。 6、InstancePerHttpRequest 在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。 ## 在MVC中使用项目代码 ## 1、Repository继承自IRepository、Services继承自IServices ![这里写图片描述][70 1] 2、设置Repository和Services的生成路径,为MVC网站的bin目录下 ![这里写图片描述][70 2] 3、在App\_Start中添加如下代码 namespace duo.CRM.Site { using Autofac; using Autofac.Integration.Mvc; using Common; using System.Reflection; using System.Web.Mvc; public class AutofacConfig { /// <summary> /// 负责调用autofac框架实现业务逻辑层和数据仓储层程序集中的类型对象的创建 /// 负责创建MVC控制器类的对象(调用控制器中的游蚕构造函数),接管DefaultControllerFactory工作 /// </summary> public static void Register() { //1.0实例化一个autofac的创建容器 var builder = new ContainerBuilder(); //2.0告诉autofac框架,将来要创建控制器类存放在哪个程序集 Assembly controllerAss = Assembly.Load("duo.CRM.Site"); builder.RegisterControllers(controllerAss); //3.0告诉autofac框架注册仓储层所在程序集中的所有类的对象实例 Assembly respAss = Assembly.Load("duo.CRM.Repository"); //创建respAss中的所有类的instance以此类的实现接口存储 builder.RegisterTypes(respAss.GetTypes()).AsImplementedInterfaces(); //4.0告诉autofac框架注册业务逻辑所在程序集中的所有类的对象实例 Assembly serAss = Assembly.Load("duo.CRM.Services"); //创建respAss中的所有类的instance以此类的实现接口存储 builder.RegisterTypes(serAss.GetTypes()).AsImplementedInterfaces(); //builder.RegisterType(typeof(sysFunctionServices)).As(typeof(IsysFunctionServices)); //5.0创建autofac的容器 var container = builder.Build(); //将container对象缓存到HttpRuntime.cache中,并且永久有效 CacheMgr.SetData(Keys.AutofacContainer, container); //Resolve方法可以从autofac容器中获取指定IsysFunctionServices的具体实现类的实体对象 //container.Resolve<IServices.IsysFunctionServices>(); //6.0将MVC的控制器对象实例 交由autofa来创建 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //我们知道控制器的创建是调用MVC默认的控制器工厂,默认的控制器工厂是调用控制器类的无参构造函数 //可是我们如果要使用AutoFac自动工厂,将对象通过构造函数注入类中,那么这个构造函数就需要带参数 //如果我们将控制器的无参构造函数删除,保留带参数的构造函数,MVC默认的控制器工厂来创建控制的时候 //就会去调用无参的构造函数,可是这时候发现没有无参的构造函数于是就报“没有为该对象定义无参数的构造函数”错误 //既然报错,那我们如果保留无参的构造函数,同时在声明一个带参数的构造函数是否可行呢? //答案;行是行,但是创建控制器的时候,MVC默认的控制器工厂调用的是无参构造函数,它并不会去调用有参的构造函数 //这时候,我们就只能将AutoFac它的控制器工厂替换调用MVC默认的控制器工厂(控制器由AutoFac的控制器工厂来创建) //而AutoFac控制器工厂在创建控制的时候只会扫描带参数的构造函数,并将对象注入到带参数的构造函数中 //AutofacDependencyResolver这个控制器工厂是继承了 IDependencyResolver接口的,而IDependencyResolver接口是MVC的东西 //MVC默认的控制器工厂名字叫:DefaultControllerFactory } } } 4、在Global.asax文件中注册 ![这里写图片描述][70 3] 5、通过构造函数注入实现DI ![这里写图片描述][70 4] [http_autofac.org]: http://autofac.org/ [https_github.com_autofac_Autofac]: https://github.com/autofac/Autofac [70]: /images/20220531/45e773ac4ac54e11a3aa3257c2625850.png [70 1]: /images/20220531/b874e260097e435198dda2944f93149a.png [70 2]: /images/20220531/8f488769b5364f4f9c91ffe7d66420d1.png [70 3]: /images/20220531/b704fd6923dd4ae5a8dba6739f0e2f8e.png [70 4]: /images/20220531/f5824c5ae0104c80abf53f3c0aefc553.png
还没有评论,来说两句吧...