• [Abp vNext 入坑分享]


    前言

    本章结束之后,这个abp vnext系列算是初步完结了,基础的组件都已经接入了。如果各位还需要其它的组件的话,可以自己按需要进行接入使用。其实这个只是一个基础的框架,可以自己根据需要进行变通的。比如:如果没有太多需求且更熟悉三层的同学可以把application和application.contract去掉就是一个三层架构了。基础是基础,用好还是要看各位对业务的理解是否够深入才能发挥好框架的作用。

    对于各个框架的使用,建议是:先使用起来,然后熟悉它,再然后改造它。并不是按照别人的标准一味的照抄,每一个框架都会有相应的痛点。。因此在使用的时候是要根据项目与团队来进行评估是否适用,若不适用的时候,如何去调整。这个不仅仅是架构师要考虑的事情。

    个人经验(仅作参考):建议每一位有想法开发人员都要保持自己的独立思考能力,无论是针对业务还是技术。但是前期是先积累技术自己验证,多在群里友好交流,不说教只分析。先从大量的文章和博客中获取知识,理出自己需要的进行沉淀。到了一定地步(这个一定地步只能看感觉,这种感觉会非常的明显,需要自己保持反思,相当于比较大的坎,越过之后就是新的开始的这种)之后,再配合一些好的收费课程和书籍去深入和系统化的学习。比如:曾经我就在群里看到一个大佬的分享然后开始入门算法,当时他分享的是hash算法,后面我有把它很白话的用场景分享给前端朋友,他也才发现原来还能这么玩。有需要的话,可以在评论区留言,我看下是否需要找个时间整理出来,可能时间会比较长一点。。

    简要说明

    【项目源码】

    【章节目录】

    本文主要介绍如何在abp vnext中使用redis和httpclient。

    首先Redis是目前应用最广泛的分布式缓存方案,这个就不进行更多的介绍了。而我们利用的组件是Microsoft.Extensions.Caching.StackExchangeRedis。此组件也是依赖于StackExchange.Redis,本文直接使用IDistributedCache来做字符的缓存,目前此接口主要是支持string与byte[]的操作,因此缓存实体也是通过序列化成字符串来进行缓存。若有更进一步的类型缓存需要的同学则可以通过StackExchange.Redis的方法来操作如:zset,list,hash等类型,这里就不作过多介绍了。到时候看情况,如果真的有很多人反馈需要的话,我再写下怎么比较完整的接入StackExchange.Redis吧!

    其次是httpclient,由于我们的系统经常会请求到各位外部的接口。因此这个的引入也是非常重要的。我们使用来管理的组件是Refit.HttpClientFactory。通过Refit.HttpClientFactory,我们可以使用接口与注解的方式来请求外部接口。管理起来非常方便,同时此组件也是通过HttpClientFactory来管理的,并不需要我们作过多的优化。

    具体步骤

    1.1、首先我们需要知道的是,我们的Redis是主要是在Application层才会需要使用的。因此,原来Host里面的引入的Redis相关组件可以删除了。定位到AbpVnext.Learn.HttpApi.Host把Microsoft.Extensions.Caching.StackExchangeRedis,Microsoft.AspNetCore.DataProtection.StackExchangeRedis卸载掉。同时删除掉Host中的Module的相关代码。

    1.2、然后我们定位到AbpVnext.Learn.Domain层安装我们需要的nuget包Microsoft.Extensions.Caching.StackExchangeRedis。定位到LearnDomainModule,增加以下代码用于注入IDistributedCache的Redis服务:

    public override void ConfigureServices(ServiceConfigurationContext context)
            {
                var configuration = context.Services.GetConfiguration();
                context.Services.AddStackExchangeRedisCache(options =>
                {
                    options.Configuration = configuration["Redis:Configuration"];
                });
            }
    

    1.3、然后我们在UserAppServices中使用IDistributedCache去操作缓存,如下:

    public async Task<UserDto> get_userbyuserid(Guid userid)
            {
                var cachekey = $"user_{userid.ToString()}";
                var userdto_str =await _distributedCache.GetStringAsync(cachekey);
                if (String.IsNullOrEmpty(userdto_str))
                {
                    var usermodel = await _repository.get_userinfo(userid);
                    if (usermodel != null)
                    {
                        var userdto = new UserDto() { Id = usermodel.Id, user_status = usermodel.user_status, user_name = usermodel.user_name, user_phone = usermodel.user_phone };
                        await _distributedCache.SetStringAsync(cachekey, Newtonsoft.Json.JsonConvert.SerializeObject(userdto));
                        return userdto;
                    }
                }
                else
                {
                    return Newtonsoft.Json.JsonConvert.DeserializeObject<UserDto>(userdto_str);
                }
       return null;
        }
    

    1.4、修改UserAppServices中的get_userbyuserid方法如下:

    public async Task<UserDto> get_userbyuserid(Guid userid)
            {
                var cachekey = $"user_{userid.ToString()}";
                var userdto_str =await _distributedCache.GetStringAsync(cachekey);
                if (String.IsNullOrEmpty(userdto_str))
                {
                    var usermodel = await _repository.get_userinfo(userid);
                    if (usermodel != null)
                    {
                        var userdto = new UserDto() { Id = usermodel.Id, user_status = usermodel.user_status, user_name = usermodel.user_name, user_phone = usermodel.user_phone };
                        await _distributedCache.SetStringAsync(cachekey, Newtonsoft.Json.JsonConvert.SerializeObject(userdto));
                        return userdto;
                    }
                }
                else
                {
                    return Newtonsoft.Json.JsonConvert.DeserializeObject<UserDto>(userdto_str);
                }
               return null;
            }
    

    然后调试项目,调用init接口,查看Redis如下:

    我们可以看到,IDistributedCache的调用String操作到了Redis里面是使用的hash结构来做存储的。

    1.5、封装一个RedisHelper来统一操作Redis,这样若是后期修改了组件也不需要修改太多的代码。如下图,

    修改UserAppServices中的方法如下:

    调试后,效果与原来的redis一致。

    2.1、接下来我们来接入Refit.HttpClientFactory,其实我们的httpclient也是在Application层才使用的。因此我们也是在Domain层进行接入。Refit的接入的话,建议是为每一个不同的外部请求的根域名定义一个接口。然后再引入,这是因为Refit注入是需要server的。下面我们拿一个微信的Api接口来做为入门例子。

    2.2、首先定义IWechatApi接口加入以下代码:

    		//获取微信公众号的access_token
            [Get("/cgi-bin/token")]
            Task<WechatAccessTokenModel> get_accesstoken(string appid, string secret, string grant_type = "client_credential");
    

    在Dommain.Shared中补充好需要的WechatAccessTokenModel。对应的是微信公众号接口返回的字段。access_token,expires_in,一般我会定义一个BaseWechatModel用于接收errcode,errmsg。如下

     public class BaseWechatModel
        {
            //错误时微信会返回错误码
            public int errcode { get; set; }
            //错误信息
            public string errmsg { get; set; }
        }
     //微信获取Access_Token的模型
        public class WechatAccessTokenModel: BaseWechatModel
        {
            public string access_token { get; set; }
            public int expires_in { get; set; }
        }
    

    2.3、接下来我们回到LearnDomainModule中,注入IWechatApi如下:

    context.Services.AddRefitClient<IWechatApi>().ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.weixin.qq.com"));
    

    然后我们在UserAppServices随便找个方法调用一下,试试效果如下则表示我调用的返回是正常的。由于我使用的appid是错误的导致的。

  • 相关阅读:
    Oracle数据类型再探:plsql能建表时能用的数据类型
    数据库中的不同类型
    数据库类型研究
    代码块,静态变量,静态代码块,运算符优先级
    JAVA运算符
    Java多线程详解
    JAVA对象序列化(Serializable、ObjectOutputStream、ObjectInputStream、 transient)
    java的IO详解
    Java死锁
    Java重载、覆写、this、super、抽象类、接口
  • 原文地址:https://www.cnblogs.com/twoBcoder/p/12968414.html
Copyright © 2020-2023  润新知