# 前言
我们知道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 } }