迷恋自留地 发表于 2021-6-7 16:09

Net5学习

本帖最后由 迷恋自留地 于 2021-6-7 16:18 编辑


### 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));
                }
```

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>());
```

### 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. ,可以没有无参数构造函数,可以支持依赖注入
3. ,可以没有无参数构造函数,可以支持依赖注入,必须要注册服务

#### FilterFactory扩展定制

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

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

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

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

4.标记在Action.上面(公众号:net分享)

yezhengw111 发表于 2021-6-7 18:59

感谢分享
页: [1]
查看完整版本: Net5学习