httpclient依赖_.NetCore 3.1高性能微服务架构:封装调用外部服务的接口方法HttpClient客户端思路分析...

护士节快乐

众所周知,微服务架构是由一众微服务组成,项目中调用其他微服务接口更是常见的操作。为了便于调用外部接口,我们的常用思路一般都是封装一个外部接口的客户端,使用时候直接调用相应的方法。webservice或WCF的做法就是引用服务,自动生成客户端。在webapi2.0里,我们都会手动封装一个静态类。那么在.netcore3.1的微服务时代,我们该如何处理这个问题呢?----思路都是一样的,封装一个外部服务,并且使用依赖注入和 HttpFactory工厂等.netcore特有的方式提升性能。接下来我们一步一步说下详细的步骤:

第1步:--创建项目

为了便于构建生成nuget包,我们一般都每个外部服务创建一个独立的项目;如下图:

b5fbb691ef322e076aa19f33244595e4.png

在解决方案里,我们创建了一个项目名为:"MuXue.Zyiz.Template.OuterClient",(项目起名一般为 公司名.部门名.项目名.xxx)。

第2步:创建一个IServiceCollection扩展服务,便于将服务注册信息。(重点)

    public static  class MsgApiClientServiceCollectionExtensions
{public static IServiceCollection AddMsgApiClient(this IServiceCollection services, IConfiguration MsgClientConfiguration)
{
services.Configure(MsgClientConfiguration)
.AddHttpClient()
.ConfigureHttpClient(config=> {
config.BaseAddress = new Uri(MsgClientConfiguration.GetSection("url").Value);
config.Timeout = TimeSpan.FromSeconds(30);
});return services;
}
}

该段代码虽然很短,但是最关键的部分:

代码的执行过程如下:

(1)  services首先注册一个操作配置文件的实例 :

services.Configure(MsgClientConfiguration)

(2) 添加HttpClientFactory工厂并且关联到services里,并将Client强制类型为IMsgApiClient(自定义的外部微服务接口名称) :

.AddHttpClient();//IMsgApiClient为接下来要创建的客户端

(3)设置HttpClient的相关配置参数:

 .ConfigureHttpClient(config=> {
config.BaseAddress = new Uri(MsgClientConfiguration.GetSection("url").Value);//外部微服务接口域名
config.Timeout = TimeSpan.FromSeconds(30); // 接口调用超时时间
});

还有如下注意点:

(1)以静态类和静态方法方式;

  (2) this IServiceCollection services ,这个参数我就不多解释了。

 (3) 一般我们都需要读取appsettings.json配置文件里的参数所以这里接收了一个参数---IConfiguration MsgClientConfiguration  ;当然如果你不需要读取配置参数,也可以忽略这个参数;

第3步:写外部接口调用的具体逻辑代码:

(1)创建一个接口,比如IMsgApiClient

 /// /// 企业微信消息发送客户端/// public interface IMsgApiClient
{/// /// 调用接口接口:向微信发送消息/// /// hrcode,多个以|隔开/// 消息内容///
Taskstring>> SendWxWorkMsgAsync(string hrcodeStr, string msg);
}

(2)实现该接口:

  /// /// 调用外部接口:向SD发送消息/// /// hrcode,多个以|隔开/// 消息内容/// public async Taskstring>> SendWxWorkMsgAsync(string hrcodeStr, string msg)
{
Result<string> result = new Result<string>();string funName = "【调用外部接口:微信企业消息推送接口】";try
{//具体的业务逻辑---根据自身业务来写
MsgApiResult sendRet = await ZyizHttpClientExtensions.PostData>(_client, _logger, "/api/weixin/work/messages/send", msgReq);if (sendRet != null)
{
_logger.LogInformation($"{funName},{hrcodeStr}推送消息成功");
result.state = true;
result.data = sendRet.Return_data.MessageId;
}else
{
result.state = false;
result.error_msg = sendRet.Return_msg;
_logger.LogError($"{funName}:{hrcodeStr}推送消息失败:{sendRet.Return_msg}");
}
}catch (Exception ex)
{
result.state = false;
result.error_code = ErrorCode.OuterApiError;
result.error_msg = funName + "调用外部接口异常:。" + ex.Message;
_logger.LogError(ex, $"{funName}向{hrcodeStr}推送消息处理异常:{ex.Message}");
}return result;
}

针对HttpClient的Post方法我特意封装了一个通用方法,如下:(可以根据自身项目自行改造)

 /// /// HttpClient扩展方法/// public class ZyizHttpClientExtensions
{/// /// httpclient-post方法的简单处理,封装成一个方法,便于调用/// /// /// /// /// http://xxx.com/后面之后的地址/// 一个对象/// /// /// public async static Task PostData(HttpClient _client, ILogger _logger,string actionUrl, dynamic param, string ContentType = "application/json", string BearerToken = "")
{string funName = "PostData";string paramStr = JsonConvert.SerializeObject(param);string jrclientguid = Guid.NewGuid().ToString("n");try
{
_logger.LogInformation($"{funName}开始,url={_client.BaseAddress},action={actionUrl},postData={paramStr} ,jrclientguid={jrclientguid}---------");
HttpResponseMessage response;using (HttpContent httpContent = new StringContent(paramStr, Encoding.UTF8))
{if (!string.IsNullOrWhiteSpace(BearerToken))
{
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", BearerToken);
}
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType);
response = await _client.PostAsync(actionUrl, httpContent);
}if (response != null && response.IsSuccessStatusCode)
{
Type t = typeof(T);if (typeof(T) == typeof(string))
{string respStr = await response.Content.ReadAsStringAsync();return (T)Convert.ChangeType(respStr, typeof(T));
}else
{string respStr = response.Content.ReadAsStringAsync().Result;
T resp = JsonConvert.DeserializeObject(respStr);return resp;
}
}else
{return default(T);
}
}catch (Exception ex)
{
_logger.LogError(ex,$"{funName}报错啦,url={_client.BaseAddress},action={actionUrl},postData={paramStr} ,jrclientguid={jrclientguid}---,ex={ex.Message}" );throw;
}finally
{
_logger.LogInformation($"{funName}结束,url={_client.BaseAddress},action={actionUrl},postData={paramStr} ,jrclientguid={jrclientguid}---------");
}
}
}

第4步:将服务注入容器:代码在Startup类的ConfigureServices方法里:

 services.AddZyizMVC(Env)
.AddZyizDbContext(Configuration)
.AddMsgApiClient(Configuration.GetSection(nameof(MsgApiClient)))//就是这行

第5步:使用:在Controller或其他地方都可以使用;

(1)首先在构造函数里注册:

  private readonly ILogger _logger;private IMsgApiClient _IMsgApiClient;public HealthController(ILogger logger,    IMsgApiClient iMsgApiClient)
{
_logger = logger;
_IMsgApiClient = iMsgApiClient;
}

(2)调用方法:

/// /// 发消息/// ///         [HttpGet]public async Taskstring>> POk()
{
Result<string> result = new Result<string>();
result = await _IMsgApiClient.SendWxWorkMsgAsync("100001002", "我是沐雪,请明天来我办公室一趟!");//result.state = true;//result.data = "连接成功";return result;
}
377f98da2b8afb286891fe77b7a09f71.pngEND

往期经典回顾

【知识点】C#语言基础原理及优缺点.NET Core中Quartz.NET的依赖注入.NetCore + Docker在Windows系统中的安装与部署在.NetCore中实现流式大文件上传 56f3df9ffbfe34b62081bd49826c8791.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值