由于HttpClient有连接释放问题,网上都是推荐用HttpClientFactory解决连接释放问题。
如下:
[Route("api/[controller]")]
[ApiController]
public class HttpClientController : ControllerBase
{
IHttpClientFactory httpClientFactory;
public HttpClientController(IHttpClientFactory factory)
{
httpClientFactory = factory;
}
[HttpGet]
[Route(nameof(Index))]
public async Task<IActionResult> Index()
{
var client = httpClientFactory.CreateClient();
var result = await client.GetAsync("http://aspnetcore.online/api/resource/getresource");
return Ok(result);
}
}
这里就引入一个问题,我不用MVC写法咋办,或者我要到dll进行得到这注入的对象咋办,就回到本质问题上了,怎么得到DotNetCore默认容器里注入的对象。按以下可以实现:
1.封装容器管理类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Core;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using LIS.Core.Const;
using LIS.Core.Util;
using System.IO;
using System.Xml;
namespace LIS.Core.Context
{
///<summary NoteObject="Class">
/// [功能描述: 框架容器,只加DotNetCore容器取对象部分示例]<br></br>
/// [创建者: zlz]<br></br>
/// [创建时间: 2021-06-17]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class ObjectContainer
{
/// <summary>
/// DotNetCore的容器句柄
/// </summary>
private static IServiceProvider NetCoreServiceProvider = null;
/// <summary>
/// 初始化DotNetCore的容器句柄
/// </summary>
/// <param name="ServiceProvider">句柄</param>
public static void InitNetCoreInstance(IServiceProvider ServiceProvider)
{
NetCoreServiceProvider = ServiceProvider;
}
/// <summary>
/// 按类型返回强类型的对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <returns>返回的对象</returns>
public static T GetNetCoreObject<T>()
{
if(NetCoreServiceProvider==null)
{
throw new Exception("启动时没初始化DotNetCore容器句柄!");
}
return NetCoreServiceProvider.GetService<T>();
}
}
}
2.添加HttpClient服务和初始化容器管理类
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using SoapCore;
namespace iMedicalLIS
{
/// <summary>
/// 开始类
/// </summary>
public class Startup
{
/// <summary>
/// 构造
/// </summary>
/// <param name="configuration"></param>
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
/// <summary>
/// 配置对象
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("webservice").ConfigureHttpMessageHandlerBuilder(builder =>
{
builder.PrimaryHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (m, c, ch, e) => true
};
});
//
services.AddMvc();
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
//初始化DotNetCore容器句柄
LIS.Core.Context.ObjectContainer.InitNetCoreInstance(app.ApplicationServices);
//使用会话
app.UseSession();
app.UseRouting();
}
}
}
3.从容器取对象使用
IHttpClientFactory factory = LIS.Core.Context.ObjectContainer.GetNetCoreObject<IHttpClientFactory>();
using (HttpClient client = factory.CreateClient())
{
client.Timeout = new TimeSpan(1,0,0);
using (var response = client.PostAsync(Address, content))
{
result = response.Result.Content.ReadAsStringAsync().Result;
client.Dispose();
//创建一个xml文档
XmlDocument xmlDoc = new XmlDocument();
//为文档导入数据
xmlDoc.LoadXml(result);
result = xmlDoc.InnerText;
//调用报错了
if (!result.Contains("<Response>"))
{
result = "<Response><SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>" + result + "</Error><Node></Node><RowCount>0</RowCount></Response>";
}
}
}
以上就包装DotNetCore容器操作,避免千篇一律的MCV取对象。方便控制台,动态库使用容器IOC服务,spring.net也按差不多方式包装容器管理类。
借用spring.net时候的思路解决了非MVC使用HttpClientFactory解决HttpClient释放问题,也得到了容器操作对象。分享给不想MVC的情况。