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. Vs Code, Visual Studio 2022, Angular and Live Server Running Through Https and IP Address

    前言 之前就写过 angular cli, vs code liveserver, vs 2019 iis express 10, vs code kestrel 使用 https + ip. 但写的 ...

  2. ASP.NET Core 单元测试

    前言 单元测试是好, 但是也很花时间. 有些功能封装好了以后也不怎么会再打开, 所以通常就是徒手测试一下, 过了就过了. 但是往往就是那么神奇, 就是会有需求漏掉. 后来要加, 又由于不想潜水, 对自 ...

  3. c++中字符/串->整数

    char字符->整数数字:std::isdigit 用于判断某个字符是否为数字(0-9). 字符串->数字:std::stoi 用于将字符转换为整数. int isdigit( int c ...

  4. 关于 vue3 中的 fragment 组件

    vue3 中的模板中只能返回一个元素 ,否则报错,使用 fragment 组件可以返回多个元素标签

  5. google 搜索技巧

    size qq.com inurl : size 指定网站 inurl 这个网站的指定内容 filetype 指定搜索的文件类型

  6. 0608-nn和autograd的区别

    0608-nn和autograd的区别 目录 一.nn 和 autograd 的区别 二.Function 和 Module 在实际中使用的情况 pytorch完整教程目录:https://www.c ...

  7. 东方通信基于 KubeSphere 的云计算落地经验

    作者:周峰 吴昌泰 公司简介 东方通信股份有限公司(以下简称"东方通信")创立于 1958 年,是一家集硬件设备.软件.服务为一体的整体解决方案提供商.公司于 1996 年成功改制 ...

  8. 云原生爱好者周刊 | 使用 WASM 来写博客是什么感觉?

    开源项目推荐 zzhack zzhack 是一个静态博客框架,是一个纯正的 WASM 应用,它由 Rust & Yew 来作为技术栈进行搭建,UI 设计比较美观,大家也可以直接使用该项目的设计 ...

  9. HTML5+CSS3+JavaScript网页实战

    1. HTML5基础 HTML5,作为构建和呈现网页内容的标准标记语言,带来了许多革命性的变化.它不仅提供了更加语义化的标签,使得网页内容更具可读性和可访问性,还增加了对多媒体的原生支持,无需依赖第三 ...

  10. 一份阅读量30万+免费且全面的C#/.NET面试宝典

    前言 C#/.NET/.NET Core相关技术常见面试题汇总,不仅仅为了面试而学习,更多的是查漏补缺.扩充知识面和大家共同学习进步.该知识库主要由自己平时学习实践总结.网上优秀文章资料收集(这一部分 ...