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容器:那么如何使用?第三方容器
- Nuget引入程式包
autofac - 創建containerBuilder
- 注冊首先和實作的關系
- Build一下,得到ConTainer容器
- 用去獲取服務實體
- 使用服務
代碼實作
//建構式注入
//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生命周期
- 瞬時生命周期 ---每一期獲取物件都是一個全新的實體(默認的生命)
{ //瞬時生命周期 ---每一期獲取物件都是一個全新的實體(默認的生命)
//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));
}
- 單例生命周期---在整個行程中,物件永遠都是同一個實體(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));
}
-
每個生命周期范圍一個實體--同一個生命周期范圍內是同一個實體,不同的生命周期范圍,實體不一樣; (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)); } -
每個【匹配生命周期范圍一個實體】(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));
}
-
每個請求一個實體(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是一個第三方容器
- 指定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());
-
在Startup類增加ConfigureContainer方法,注冊關系
public void ConfigureContainer(ContainerBuilder containerBuilder) { containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>(); }Autofac支持控制器屬性注入
控制器是一個類, 控制器的實體其實是IControllerActivator來創建的;
- 得讓控制器使用容器來獲取實體;
- 注冊控制器抽象和具體的關系
var controllersTypesInAssembly = typeof (Startup) .Assembly . GetExportedTypes() .Where(type => typeof (ControllerBase) .ISAssi gnab1eFrom(type)). ToArray(); builder .RegisterTypes (control1ersTypes InAssemb1y) . PropertiesAutowired(new AutowiredpropertySelector(); -
在控制器內定義屬性
-
擴展,自己控制究竟哪些屬性需要做依賴注入
//指定控制器實體讓容器來創建
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
Autofac抽象多實作的問題
- 一個抽象多個實體,都注冊了,通過建構式用抽象型別來獲取實體,哪個后面注冊就獲取到哪一個;覆寫型;
- 個抽象多個實體,都注冊了,可以通過一個IEnumerable<抽象> ,當做建構式引數,可以獲取到所有注冊的具體的實體;
- 注冊一個抽象的多個實體資源,如下方式注冊,可以在控制器的建構式中,使用具體實作型別作為引數型別,可以匹配到不同到具體
型別實體
ontainerBuilder.RegisterSource (new AnyConcreteTypeNotAlreadyRegisteredsource(t =>
t. IsAssignab1eTo<IestServiceA>());
AOP 5個Filter
AOP:可以在不修改之前的代碼為基礎,可以動態的增加新功能;
AuthorizationFilter鑒權授權
ResourceFilter資源
ExceptionFilter例外
ActionFilter方法
ResultFilter
ActionFilter的特點
自定義一個CustomActionFilterAttribute特性,繼承Attribute, 實作IActionFilter介面; 實作方法,標記在Action上;
請求標記的有CustomActionFilterAttribute的Action:執行順序如下:
- 執行控制器建構式
- 執行CustomActionFilterAttribute內的OnActionExecuting方法
- 執行Action .
- 執行CustomActionFilterAttribute內的OnActionExecuted
ActionFiler 的多種實作
- 通過實作IActionFilter介面來完成擴展
- 通過繼承ActionFilterAltribute (系統提供的實作) , 根據自己的需要,覆寫不同的方法,達到自己的訴求
- 異步版本的實作,通過實作IAsyncActionFilter介面來實作
Filter 的多種注冊和擴展
- [CustomActioniter--Fitler必須有無引數建構式
- [TypeFilter(typeof(CustomActionFiterAttributel)],可以沒有無引數建構式,可以支持依賴注入
- [ServiceFilter(typeof(CustomActionFilterAttributel)],可以沒有無引數建構式,可以支持依賴注入,必須要注冊服務
FilterFactory擴展定制
可以使用ServiceFilter/TypeFilter就可以支持依賴注入呢? --_-定是IOC容器來完成;
1.自定義一個特性類,繼承Attribute,實作介面IFilterFactory; 實作介面中的方法
2.通過建構式傳遞需要實體化的特性的type型別
3.在實作介面中,通過Type型別獲取到實體
4.標記在Action.上面

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/285376.html
標籤:.NET Core
