Net5學習筆記


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.上面


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM