# 前言
我們知道asp.net core是一個自帶IOC容器的web框架,在startup.cs services中Add()方法去注入一些Microsoft.Extensions
模塊,比如**Microsoft.Extensions.Configuration.Logging,Microsoft.Extensions.Http**等
public void ConfigureServices(IServiceCollection services) { services.AddLogging(); services.AddSignalR(); services.AddHttpClient(); }
這些官方擴展組件很實用,比如在一個WPF項目中我們會用到大量的http請求,在過去很多時候我們這樣去寫:
public async Task GetDataAsync() { var client=new HttpClient(); client.BaseAddress=new Uri("http://www.baidu.com"); var response= await client.GetAsync("http://www.baidu.com"); if(response.StatusCode==HttpStatusCode.OK) { //Dosomething } else { //Dosomething } }
在大量的http請求后以上代碼將是操作系統中的tcp連接耗盡詳見:https://news.cnblogs.com/n/553217
Microsoft.Extensions
.Http組件可以讓我們創建Httpfactory 去創建我們的HttpClient。在asp.net core中這樣使用
private readonly IHttpClientFactory _httpClientFactory; public HomeController(IHttpClientFactory httpClientFactory) { this._httpClientFactory = httpClientFactory; var client= _httpClientFactory.CreateClient(); //DoSomething }
那么如果我們想在WPF中使用這些擴展組件該如何去做呢?在所有的WPF的mvvm框架中我最最推崇使用Prism框架,獨立的模塊化設計易於
單元測試和復用,非常容易的View和ViewModel綁定,優秀的事件聚合和復合命令等。而輕量級的MvvmLight框架在項目變大了之后就很
難維護和模塊解耦,同時如果想在MvvmLight 中使用以上組件要自己寫不少代碼即使依賴autofac擴展MvvmLight中自身容器的不足也難
做到View和ViewModel的生命周期管控,作者也在加盟了MicroSoft.Azure后不在對框架進行更新了。那今天就來介紹下在Prism中如何
使用Microsoft.Extensions.*的擴展包。由於在Prism 6.3之后移除了Prism.Mef,在Prism 7.1.0.431移除了對Autofac的支持,
在7.2.0.1422后移除了對Prism.Ninject的支持,只保留了Unity和DryIoc這兩個第三方容器的支持,但可以繼承
PrismApplicationBase實現第三方的IOC容器管控各種組件注入和生命周期。還可以重寫IContainerExtension
CreateContainerExtension()方法實現容器擴展,我們以UnityContainer為例:
protected override IContainerExtension CreateContainerExtension() { var container = new UnityContainer(); return PrismContainerExtension.Create(container); }
# 在WPF Prism框架中使用IServiceCollection、
其中PrismContainerExtension在Prism.Unity.Extensions包中。使用之前使用命令:
Install-Package Prism.Unity.Extensions
來安裝Unity容器擴展。這樣就可以把 .net core 自帶的IServiceCollection中注入的組件注入到由Prism提供的容器,使用別的其他
容器可以實現IContainerExtension接口來擴展容器。在prism.container.extensions庫當中實現了IContainerRegistry的擴展方法:
public static IContainerRegistry RegisterServices(this IContainerRegistry containerRegistry, Action<IServiceCollection> registerServices) { IServiceCollectionAware serviceCollectionAware = containerRegistry as IServiceCollectionAware; if (serviceCollectionAware != null) { serviceCollectionAware.RegisterServices(registerServices); } else { ServiceCollection serviceCollection = new ServiceCollection(); egisterServices(serviceCollection); IServiceProviderExtensions.RegisterTypesWithPrismContainer(containerRegistry, serviceCollection); } return containerRegistry; }
這樣可以在重寫 RegisterTypes方法時
protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterServices(AddServiceCollections); } private static void AddServiceCollections(IServiceCollection services) { services.AddHttpClient(); var log = new LoggerConfiguration() .WriteTo.Console(LogEventLevel.Debug) .WriteTo.Debug(LogEventLevel.Debug) .WriteTo.File("log/log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true) .CreateLogger(); services.AddLogging(c => { c.AddSerilog(log); }); }
RegisterServices需要傳入一個Action<IServiceCollection>。Prism中的IOC容器就可以使用IServiceCollection.Add()方法
中注入的擴展組件了。當你的View設置了prism:ViewModelLocator.AutoWireViewModel="True" 之后IHttpClientFactory將自
動注入到ViewModel的構造器中。
public class MainViewModel:BindableBase { private readonly IHttpClientFactory _httpClientFactory; public MainViewModel(IHttpClientFactory httpClientFactory) { this._httpClientFactory = httpClientFactory; var client= _httpClientFactory.CreateClient(); //DoSomething } }