ASP.NET Core快速入門(第3章:依賴注入)--學習筆記
課程鏈接:http://video.jessetalk.cn/course/explore
良心課程,大家一起來學習哈!
任務16:介紹
1、依賴注入概念詳解
- 從UML和軟件建模來理解
- 從單元測試來理解
2、ASP.NET Core 源碼解析
任務17:從UML角度來理解依賴
1、什么是依賴
當一個類A完成某個任務需要另一個類B來幫助時,A就對B產生了依賴
例如CustomerController需要對customer進行新增或查找時用到EF,則對EF的Context產生了依賴
var context = new CustomerContext(new DbContextOptions<CustomerContext>{});
2、顯示依賴與隱式依賴
顯示依賴:把一個類用到的所有外部組件放到一個類最上面,在構造函數里面初始化
private CustomerContext _context;
public CustomerController()
{
_context = new CustomerContext(new DbContextOptions<CustomerContext>{});
}
隱式依賴:需要用到的地方再初始化,不推薦
var context = new CustomerContext(new DbContextOptions<CustomerContext>{});
3、依賴倒置原則
依賴高層業務,不依賴低層業務的具體實現,而依賴于具體的抽象
CustomerController是高層業務的一個組件,依賴于CustomerContext是一個低層數據庫的實現,如果現在需要把EF換成一個內存的實現或者mysql,需要修改CustomerController類,風險很大,所以應該依賴于低層業務的抽象
把低層業務方法抽象,比如查找,新增,抽象出一個接口,當不需要使用EF的時候,使用內存的實現替換
private ICustomerRepository _customerRepository;
public CustomerController()
{
_customerRepository = new EfCustomerRepository(
new CustomerContext(new DbContextOptions<CustomerContext>{}));
}
任務18:控制反轉
實現依賴注入的方式不由自己決定,而是交給一個IOC容器,需要什么由容器傳入,比如生產環境需要使用EF,則由容器傳入一個EfCustomerRepository,而測試環境需要使用內存級別的,則傳入一個MemoryCustomerRepository
private ICustomerRepository _customerRepository;
public CustomerController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
任務19:單元測試
var repository = new Data.MemoryCustomerRepository();
var controller = new CustomerController(repository);// 通過外部控制Controller里面的依賴
var customer = new Model.Customer()
{
FirstName = "Mingson",
LastName = "Zheng",
Phone = "123456789",
};
var result = controller.Add(customer);
Assert.IsType<OkResult>(result);// 正確結果
var resultBad = controller.Add(customer);
Assert.IsType<BadRequestObjectResult>(resultBad);// 錯誤結果
通過單元測試可以得知修改Bug過程中是否誤刪代碼,導致原來通過的測試現在無法通過。
任務20:DI初始化的源碼解讀
Microsoft.AspNetCore.Hosting.WebHostBuilder
/// <summary>
/// Builds the required services and an <see cref="T:Microsoft.AspNetCore.Hosting.IWebHost" /> which hosts a web application.
/// </summary>
public IWebHost Build()
{
......
// 第一步,build
IServiceCollection serviceCollection1 = this.BuildCommonServices(out hostingStartupErrors);
// 第二步,獲取ServiceCollection,ServiceProvider
IServiceCollection serviceCollection2 = serviceCollection1.Clone();
IServiceProvider providerFromFactory = GetProviderFromFactory(serviceCollection1);
......
// 第三步,new一個WebHost,傳入ServiceCollection,ServiceProvider
WebHost webHost = new WebHost(serviceCollection2, providerFromFactory, this._options, this._config, hostingStartupErrors);
......
// 第四步,webHost初始化方法Initialize
webHost.Initialize();
......
}
第一步BuildCommonServices中new一個ServiceCollection就是在startup接口中使用
private IServiceCollection BuildCommonServices(
out AggregateException hostingStartupErrors)
{
......
ServiceCollection services = new ServiceCollection();
// new完之后添加一些初始化操作
......
return (IServiceCollection) services;
}
IStartup接口
namespace Microsoft.AspNetCore.Hosting
{
public interface IStartup
{
IServiceProvider ConfigureServices(IServiceCollection services);
void Configure(IApplicationBuilder app);// 配置管道
}
}
第四步,webHost初始化方法Initialize
public void Initialize()
{
......
this.EnsureApplicationServices();
......
}
private void EnsureApplicationServices()
{
......
this.EnsureStartup();
this._applicationServices = this._startup.ConfigureServices(this._applicationServiceCollection);
}
private void EnsureStartup()
{
if (this._startup != null)
return;
this._startup = this._hostingServiceProvider.GetService<IStartup>();
if (this._startup == null)
throw new InvalidOperationException(string.Format("No startup configured. Please specify startup via WebHostBuilder.UseStartup, WebHostBuilder.Configure, injecting {0} or specifying the startup assembly via {1} in the web host configuration.", (object) "IStartup", (object) "StartupAssemblyKey"));
}
任務21:依賴注入的使用
了解ASP.NET Core 依賴注入,看這篇就夠了:
http://www.jessetalk.cn/2017/11/06/di-in-aspnetcore/

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。
歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含鏈接: http://www.rzrgm.cn/MingsonZheng/ ),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布。
如有任何疑問,請與我聯系 (MingsonZheng@outlook.com) 。


浙公網安備 33010602011771號