Loading... 什么是Ioc 把对象的统一创建交给第三方容器来创建 Inversion of Control,英文缩写为IoC,不是什么技术,而是一种设计思想。 ### Autofac容器初识 auto 是一款有优秀的IOC容器:那么如何使用?第三方容器 1. Nuget引入程序包`autofac` 2. 创建containerBuilder 3. 注册首先和实现的关系 4. Build一下,得到ConTainer容器 5. 用去获取服务实例 6. 使用服务 代码实现 ``` //构造函数注入 //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>(); //containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>(); //containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>(); //IContainer container = containerBuilder.Build(); //TestServiceB testServiceb = container.Resolve<TestServiceB>();//获取服务 //testServiceb.Show(); ``` ### Autofac多种注入方式 构造函数注入 ``` { ////构造函数注入 //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>(); //containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>(); //containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>(); //IContainer container = containerBuilder.Build(); //ITestServiceB testServiceb = container.Resolve<ITestServiceB>();//获取服务 //testServiceb.Show(); } ``` 属性注入 ``` //{ // ContainerBuilder containerBuilder = new ContainerBuilder(); // containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>(); // containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>(); // containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>(); // containerBuilder.RegisterType<TestServiceD>().As<ITestServiceD>().PropertiesAutowired(); // IContainer container = containerBuilder.Build(); // ITestServiceD testServiceD = container.Resolve<ITestServiceD>();//获取服务 // testServiceD.Show(); //} ``` 方法注入 ``` //{ // ContainerBuilder containerBuilder = new ContainerBuilder(); // containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>(); // //containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>(); // containerBuilder.RegisterType<TestServiceB>().OnActivated(e => e.Instance.SetService(e.Context.Resolve<ITestServiceA>())).As<ITestServiceB>(); // containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>(); // containerBuilder.RegisterType<TestServiceD>().As<ITestServiceD>().PropertiesAutowired(); // IContainer container = containerBuilder.Build(); // ITestServiceB testServiceb = container.Resolve<ITestServiceB>();//获取服务 // testServiceb.Show(); //} ``` ### Autofac生命周期 1. 瞬时生命周期 ---每一期获取对象都是一个全新的实例(默认的生命) ``` { //瞬时生命周期 ---每一期获取对象都是一个全新的实例(默认的生命) //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerDependency(); //IContainer container = containerBuilder.Build(); //ITestServiceA testServiceA = container.Resolve<ITestServiceA>();//获取服务 //ITestServiceA testServiceA1 = container.Resolve<ITestServiceA>();//获取服务 //Console.WriteLine(object.ReferenceEquals(testServiceA, testServiceA1)); } ``` 2. 单例生命周期---在整个进程中,对象永远都是同一个实例(SingleInstance) ``` { //单例生命周期---在整个进程中,对象永远都是同一个实例(SingleInstance) //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().SingleInstance(); //IContainer container = containerBuilder.Build(); //ITestServiceA testServiceA = container.Resolve<ITestServiceA>();//获取服务 //ITestServiceA testServiceA1 = container.Resolve<ITestServiceA>();//获取服务 //Console.WriteLine(object.ReferenceEquals(testServiceA, testServiceA1)); } ``` 3. 每个生命周期范围一个实例--同一个生命周期范围内是同一个实例,不同的生命周期范围,实例不一样; (InstancePerLifetimeScope) ``` { //每个生命周期范围一个实例--同一个生命周期范围内是同一个实例,不同的生命周期范围,实例不一样; (InstancePerLifetimeScope) //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerLifetimeScope(); //IContainer container = containerBuilder.Build(); //ITestServiceA testServiceA15 = null; //ITestServiceA testServiceA16 = null; //using (var scope1 = container.BeginLifetimeScope()) //生命周期范围 //{ // ITestServiceA testServiceA11 = scope1.Resolve<ITestServiceA>(); // ITestServiceA testServiceA12 = scope1.Resolve<ITestServiceA>(); // Console.WriteLine(object.ReferenceEquals(testServiceA11, testServiceA12)); // testServiceA15 = testServiceA12; //} //using (var scope1 = container.BeginLifetimeScope()) //{ // ITestServiceA testServiceA13 = scope1.Resolve<ITestServiceA>(); // ITestServiceA testServiceA14 = scope1.Resolve<ITestServiceA>(); // Console.WriteLine(object.ReferenceEquals(testServiceA13, testServiceA14)); // testServiceA16 = testServiceA14; //} //Console.WriteLine(object.ReferenceEquals(testServiceA15, testServiceA16)); } ``` 4. 每个【匹配生命周期范围一个实例】(InstancePerMatchingLifetimeScope(名称)) ``` { //每个【匹配生命周期范围一个实例】(InstancePerMatchingLifetimeScope(名称)) //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerMatchingLifetimeScope("Zhaoxi"); //IContainer container = containerBuilder.Build(); //ITestServiceA testServiceA15 = null; //ITestServiceA testServiceA16 = null; //using (var scope1 = container.BeginLifetimeScope("Zhaoxi")) //{ // ITestServiceA testServiceA11 = scope1.Resolve<ITestServiceA>(); // using (var scope2 = scope1.BeginLifetimeScope()) // { // ITestServiceA testServiceA12 = scope2.Resolve<ITestServiceA>(); // Console.WriteLine(object.ReferenceEquals(testServiceA11, testServiceA12)); // } // testServiceA15 = testServiceA11; //} //using (var scope1 = container.BeginLifetimeScope("Zhaoxi")) //{ // ITestServiceA testServiceA13 = scope1.Resolve<ITestServiceA>(); // using (var scope2 = scope1.BeginLifetimeScope()) // { // ITestServiceA testServiceA14 = scope2.Resolve<ITestServiceA>(); // Console.WriteLine(object.ReferenceEquals(testServiceA13, testServiceA14)); // } // testServiceA16 = testServiceA13; //} //Console.WriteLine(object.ReferenceEquals(testServiceA15, testServiceA16)); } ``` 5. 每个请求一个实例(InstancePerRequest) ---mvc中 ``` ////每个请求一个实例(InstancePerRequest) //ContainerBuilder containerBuilder = new ContainerBuilder(); //containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().InstancePerRequest(); //IContainer container = containerBuilder.Build(); //ITestServiceA testServiceA11 = container.Resolve<ITestServiceA>(); //ITestServiceA testServiceA12 = container.Resolve<ITestServiceA>(); //Console.WriteLine(object.ReferenceEquals(testServiceA11, testServiceA12)); ``` ### Autofac支持配置文件 Nuget引入支持配置文件: Autofac. Extensions.DependencyInjection Aputofac.Configuration Autofac ``` { //ContainerBuilder containerBuilder = new ContainerBuilder(); //// 就可以在这里写入Autofac注入的各种 //{ // //读取配置文件,把配置关系装载到ContainerBuilder // IConfigurationBuilder config = new ConfigurationBuilder(); // IConfigurationSource autofacJsonConfigSource = new JsonConfigurationSource() // { // Path = "CfgFile/autofac.json", // Optional = false,//boolean,默认就是false,可不写 // ReloadOnChange = true,//同上 // }; // config.Add(autofacJsonConfigSource); // ConfigurationModule module = new ConfigurationModule(config.Build()); // containerBuilder.RegisterModule(module); //} //IContainer container = containerBuilder.Build(); //ITestServiceA testServiceA = container.Resolve<ITestServiceA>(); //ITestServiceD testServiceD = container.Resolve<ITestServiceD>(); //testServiceD.Show(); } ``` ### Autofac整合 Autofac是一个第三方容器 1. 指定Autofac工厂替换默认工厂,Program指定 Program中CreateHostBuilder的hostbuilder添加`.UseServiceProviderFactory(new AutofacServiceProviderFactory()); ` ``` var hostbuilder = Host.CreateDefaultBuilder(args) //创建一个默认的主机builder //.ConfigureLogging(loggingBuilder=> //{ //配置log4Net配置文件的读取 // loggingBuilder.AddLog4Net("CfgFile/log4net.Config"); //}) .ConfigureWebHostDefaults(webBuilder => //配置成一个默认的Web主机 { webBuilder.UseStartup<Startup>(); //使用Startup文件来实现配置 }).UseServiceProviderFactory(new AutofacServiceProviderFactory()); ``` 2. 在Startup类增加ConfigureContainer方法,注册关系 ``` public void ConfigureContainer(ContainerBuilder containerBuilder) { containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>(); } ``` ### Autofac支持控制器属性注入 控制器是一个类, 控制器的实例其实是IControllerActivator来创建的; 1. 得让控制器使用容器来获取实例; 2. 注册控制器抽象和具体的关系 ``` var controllersTypesInAssembly = typeof (Startup) .Assembly . GetExportedTypes() .Where(type => typeof (ControllerBase) .ISAssi gnab1eFrom(type)). ToArray(); builder .RegisterTypes (control1ersTypes InAssemb1y) . PropertiesAutowired(new AutowiredpropertySelector(); ``` 3. 在控制器内定义属性 4. 扩展,自己控制究竟哪些属性需要做依赖注入 ``` //指定控制器实例让容器来创建 services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>()); ``` ### Autofac抽象多实现的问题 1. 一个抽象多个实例,都注册了,通过构造函数用抽象类型来获取实例,哪个后面注册就获取到哪一个;覆盖型; 2. 个抽象多个实例,都注册了,可以通过一个IEnumerable<抽象> ,当做构造函数参数,可以获取到所有注册的具体的实例; 3. 注册一个抽象的多个实例资源,如下方式注册,可以在控制器的构造函数中,使用具体实现类型作为参数类型,可以匹配到不同到具体 类型实例 ``` ontainerBuilder.RegisterSource (new AnyConcreteTypeNotAlreadyRegisteredsource(t => t. IsAssignab1eTo<IestServiceA>()); ``` 笔记记录于朝夕教育Net5学习 ![](https://img-blog.csdnimg.cn/20210517111144223.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_1,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_7#pic_center) 最后修改:2021 年 07 月 24 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏