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

第1步:--创建项目

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


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

第2步:创建一个IServiceCollection扩展服务,便于将服务注册信息。(重点)
public static  class MsgApiClientServiceCollectionExtensions
    {
        public static IServiceCollection AddMsgApiClient(this IServiceCollection services ICo
nfiguration MsgClientConfiguration)
        {
            services.Configure<MsgClientConfiguration>(MsgClientConfiguration)
                    .AddHttpClient<IMsgApiClient MsgApiClient>()
                    .ConfigureHttpClient(config=> {
                        config.baxxxxseAddress = new Uri(MsgClientConfiguration.GetSection("url").Value);
                        config.Timeout = TimeSpan.FromSeconds(30);
                        });

            return services;
        }
    }

该段代码虽然很短,但是最关键的部分:
代码的执行过程如下:
(1)  services首先注册一个操作配置文件的实例 :
services.Configure<MsgClientConfiguration>(MsgClientConfiguration)
(2) 添加HttpClientFactory工厂并且关联到services里,并将Client强制类型为IMsgApiClient(自定义的外部微服务接口名称) :
.AddHttpClient<IMsgApiClient MsgApiClient>();//IMsgApiClient为接下来要创建的客户端
(3)设置HttpClient的相关配置参数:

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

还有如下注意点:
(1)以静态类和静态方法方式;
  (2) this IServiceCollection services ,这个参数我就不多解释了。
(3) 一般我们都需要读取appsettings.json配置文件里的参数所以这里接收了一个参数---ICo
nfiguration MsgClientConfiguration  ;当然如果你不需要读取配置参数,也可以忽略这个参数;
第3步:写外部接口调用的具体逻辑代码:

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

/// <summary>
    /// 企业消息发送客户端
    /// </summary>
    public interface IMsgApiClient
    {

        /// <summary>
        /// 调用接口接口:向发送消息
        /// </summary>
        /// <param name="hrcodeStr">hrcode,多个以|隔开</param>
        /// <param name="msg">消息内容</param>
        /// <returns></returns>
        Task<Result<string>> SendWxWorkMsgAsync(string hrcodeStr string msg);

    }

(2)实现该接口:

/// <summary>
        /// 调用外部接口:向SD发送消息
        /// </summary>
        /// <param name="hrcodeStr">hrcode,多个以|隔开</param>
        /// <param name="msg">消息内容</param>
        /// <returns></returns>
        public async Task<Result<string>> SendWxWorkMsgAsync(string hrcodeStr string msg)
        {
            Result<string> result = new Result<string>();
            string funName = "【调用外部接口:企业消息推送接口】";
            try
            {
                //具体的业务逻辑---根据自身业务来写
                MsgApiResult<WeiXinWorkMessageResponse> sendRet = await UPCHttpClientExtensions.PostData<MsgApiResult<WeiXinWorkMessageResponse>>(_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;
                    _msg = sendRet.Return_msg;
                    _logger.LogError($"{funName}:{hrcodeStr}推送消息失败:{sendRet.Return_msg}");
                }

            }
            catch (Exception ex)
            {
                result.state = false;
                _code = ErrorCode.OuterApiError;
                _msg = funName + "调用外部接口异常:。" + ex.Message;
                _logger.LogError(ex $"{funName}向{hrcodeStr}推送消息处理异常:{ex.Message}");
            }


            return result;

        }
针对HttpClient的Post方法我特意封装了一个通用方法,如下:(可以根据自身项目自行改造)
/// <summary>
  /// HttpClient扩展方法
  /// </summary>
    public class UPCHttpClientExtensions
    {
如何生成webservice客户端        /// <summary>
        /// httpclient-post方法的简单处理,封装成一个方法,便于调用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_client"></param>
        /// <param name="_logger"></param>
        /// <param name="actionUrl">xxx/后面之后的地址</param>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。