IOC 容器IServiceCollection

什么是Ioc

把对象的统一创建交给第三方容器来创建

如何使用内置IOC ServerCollection

1.在Starup中的ConfigurServicetion方法中注册服务

services.AddSingleton<ITestServiceA, TestServiceA>();

---------------
private readonly IServiceProvider _ServiceProvider = null; ITestServiceA testServiceA = (ITestServiceA)_ServiceProvider.GetService(typeof(ITestServiceA));
testServiceA.Show();

2.在使用的控制器中,通过构造函数,定义服务的抽象类型,作为参数,在运行时,得到具体的服务

3.调用服务内的方法

(视图中可以使用@inject获取实列)

DI依赖注入:IServerConcetion支持构造函数注入

什么是依赖注入

如果对象a依赖对象b,对象b依赖对象c,就可以了先构造对象c传递给对象b,然后把b传递给a

IServer可以支持无限级层的依赖注入;前提是都要先注入服务(注册抽象和集体的映射关系)

IserverCollention生命周期

那么再创建对象的时候,不同情况,不需要让对象单列,每一次都创建新的对象实列;不同的作用于新的实例

瞬时生命周期:AddTransient 每一次getService获取的实例都是不同的实例(项目中更多的使用)

单例生命周期:AddSingleton单例生命周期,在整个进程中获取的都是同一个实例

作用域生命周期:AddScoped 同一个作用域,获取的是同一个对象的实例;不同的作用域,获取的是不同的对象实例

#region IServiceCollection生命周期解析

            //瞬时生命周期
{
//IServiceCollection serviceCollection = new ServiceCollection();
//serviceCollection.AddTransient<ITestServiceA, TestServiceA>(); //瞬时生命周期,每一次getService获取的实例都是不同的实例
//ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
//ITestServiceA testServiceA = serviceProvider.GetService<ITestServiceA>();
//ITestServiceA testServiceA1 = serviceProvider.GetService<ITestServiceA>();
//bool isOK = object.ReferenceEquals(testServiceA, testServiceA1); //结果为false; 两次获取的对象不是同一个实例
} //单例生命周期
{
//IServiceCollection serviceCollection = new ServiceCollection();
//serviceCollection.AddSingleton<ITestServiceA, TestServiceA>(); //单例生命周期,在整个进程中获取的都是同一个实例
//ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
//ITestServiceA testServiceA = serviceProvider.GetService<ITestServiceA>();
//ITestServiceA testServiceA1 = serviceProvider.GetService<ITestServiceA>();
//bool isOK = object.ReferenceEquals(testServiceA, testServiceA1); //结果为 true,是同一个引用,在整个进程中获取的都是同一个实例
} ///作用域生命周期
{
//IServiceCollection serviceCollection = new ServiceCollection();
//serviceCollection.AddScoped<ITestServiceA, TestServiceA>(); //作用域生命周期;同一个作用域,获取的是同一个对象的实例;不同的作用域,获取的是不同的对象实例
//ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
//ITestServiceA testServiceA = serviceProvider.GetService<ITestServiceA>();
//ITestServiceA testServiceA1 = serviceProvider.GetService<ITestServiceA>(); //bool isOK = object.ReferenceEquals(testServiceA, testServiceA1); //ServiceProvider serviceProvider1 = serviceCollection.BuildServiceProvider();
//ITestServiceA testServiceA2 = serviceProvider1.GetService<ITestServiceA>();
//bool isOK1 = object.ReferenceEquals(testServiceA1, testServiceA2);
} #endregion

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));
}
  1. 单例生命周期---在整个进程中,对象永远都是同一个实例(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));
}
  1. 每个生命周期范围一个实例--同一个生命周期范围内是同一个实例,不同的生命周期范围,实例不一样; (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));
    }
  2. 每个【匹配生命周期范围一个实例】(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));
}
  1. 每个请求一个实例(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());
  1. 在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();
  2. 在控制器内定义属性

  3. 扩展,自己控制究竟哪些属性需要做依赖注入

//指定控制器实例让容器来创建
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

Autofac抽象多实现的问题

  1. 一个抽象多个实例,都注册了,通过构造函数用抽象类型来获取实例,哪个后面注册就获取到哪一个;覆盖型;
  2. 个抽象多个实例,都注册了,可以通过一个IEnumerable<抽象> ,当做构造函数参数,可以获取到所有注册的具体的实例;
  3. 注册一个抽象的多个实例资源,如下方式注册,可以在控制器的构造函数中,使用具体实现类型作为参数类型,可以匹配到不同到具体

    类型实例
ontainerBuilder.RegisterSource (new AnyConcreteTypeNotAlreadyRegisteredsource(t =>
t. IsAssignab1eTo<IestServiceA>());

AOP 5个Filter

AOP:可以在不修改之前的代码为基础,可以动态的增加新功能;

AuthorizationFilter鉴权授权

ResourceFilter资源

ExceptionFilter异常

ActionFilter方法

ResultFilter

ActionFilter的特点

自定义一个CustomActionFilterAttribute特性,继承Attribute, 实现IActionFilter接口; 实现方法,标记在Action上;

请求标记的有CustomActionFilterAttribute的Action:执行顺序如下:

  1. 执行控制器构造函数
  2. 执行CustomActionFilterAttribute内的OnActionExecuting方法
  3. 执行Action .
  4. 执行CustomActionFilterAttribute内的OnActionExecuted

ActionFiler 的多种实现

  1. 通过实现IActionFilter接口来完成扩展
  2. 通过继承ActionFilterAltribute (系统提供的实现) , 根据自己的需要,覆写不同的方法,达到自己的诉求
  3. 异步版本的实现,通过实现IAsyncActionFilter接口来实现

Filter 的多种注册和扩展

  1. [CustomActioniter--Fitler必须有无参数构造函数
  2. [TypeFilter(typeof(CustomActionFiterAttributel)],可以没有无参数构造函数,可以支持依赖注入
  3. [ServiceFilter(typeof(CustomActionFilterAttributel)],可以没有无参数构造函数,可以支持依赖注入,必须要注册服务

FilterFactory扩展定制

可以使用ServiceFilter/TypeFilter就可以支持依赖注入呢? --_-定是IOC容器来完成;

1.自定义一个特性类,继承Attribute,实现接口IFilterFactory; 实现接口中的方法

2.通过构造函数传递需要实例化的特性的type类型

3.在实现接口中,通过Type类型获取到实例

4.标记在Action.上面

Net5学习笔记的更多相关文章

  1. net5学习笔记---依赖注入

    小王的故事 小王去上班 ​ 小王是个程序员,每个工作日他都要去上班,诸多交通工具他最喜欢的交通工具是骑电车.在骑行的过程中放空自己使他很快. ​ 突然有一天天气预报说近期有很大的雨,小王再想骑电车去上 ...

  2. .NET 5学习笔记(10)——Entity Framework Core之切换SQLServer和SQLite

    上一篇我们梳理了CodeFist的一般流程,本篇我们讨论如何在一套代码中,支持SQL Server和SQLite的切换.同时从本篇开始,我们从.NET Core 3.1 迁移到.NET 5.相信.NE ...

  3. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  4. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  5. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  6. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  7. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  8. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  9. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  10. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

随机推荐

  1. EF Core – QueryFilter & Interception

    主要参考 Global Query Filters Interceptors QueryFilter QueryFilter 就是默认过滤, 非常适合用来做 Soft Delete builder.H ...

  2. Linux操作系统和文件系统、常见命令(下)

    C语言的绝大部分内容应该记录在以.c作为拓展名的文件里,这种文件叫做C语言的源文件 C语言程序里还包括以.h作为拓展名的文件,这种文件叫头文件(只有极少数的内容可以记录在头文件里) C语言程序里可以使 ...

  3. VB.NET 在 Windows下通过WIn32API获取CPU和内存的使用率

    .net 要获取CPU和内存的使用率,一般是通过 PerformanceCounter 或者 WMI 查询得到,但是如果操作系统经常不正常断电或者别的什么原因,让系统的性能计数器抽风了,可能就会造成初 ...

  4. 读取.raw格式文件(学习记录)

    import cv2 #OpenCV包 import numpy as np # 首先确定原图片的基本信息:数据格式,行数列数,通道数 rows=886#图像的行数 cols=492#图像的列数 ch ...

  5. iOS键盘通知弹框使用小结

    项目开发中文本框输入的时候经常会用到键盘弹框遮挡的问题.解决办法就是根据底部键盘弹出的高度动态的改变对应view的位置.这里以多行文本框输入为例,效果图如下. //第一步,注册监听键盘通知 [[NSN ...

  6. Gradio 5 稳定版正式发布

    在过去的几个月里,我们一直在努力工作,今天,我们想向大家展示成果:Gradio 5 稳定版现已发布. 有了 Gradio 5,开发者可以构建 生产级的机器学习 Web 应用,这些应用不仅性能优越.可扩 ...

  7. 怎么根据token的有⽆去控制路由的跳转?进度条跳转 - 白名单是否有token - 单独封装文件permission .js

    vue这边的路由⾃带了路由前置守卫,我们可以在前置守卫⾥拿到token数据,然后根据需求做分⽀判 断,要是token存在就使⽤next⽅法正常放⾏跳转,否则可以强制跳回到登录,让⽤户去获取token ...

  8. Nuxt3+PM2集群模式启动及勘误

    起因 之前写过一篇 Nuxt3 的文章,Nuxt3 环境变量配置,用到了 PM2,但是里面的一些配置存在问题,最近有空又验证了一下,这里做一个勘误. 问题 PM2 的启动配置中有一项是exec_mod ...

  9. PostgreSQL 17重磅登场——世界上最成功的数据库

    朋友们,万众期待的 PostgreSQL 大版本发布又来了!这一次,PostgreSQL 17 带着全新的性能优化和开发者必备的新功能强势登场.与其说这是一场普通的更新,不如说它是一场专为高并发工作负 ...

  10. jenkin配置pytest+appium+allure持续集成环境

    首先配置项目: 这里建议使用自定义工作空间,可以避免git忽略提交得文件再被拉取到本地时不存在,导致得一些问题(因为有些配置文件可能不想提交到github,所以这样配置更合理一些,哈哈) git配置: ...