首页后端开发ASP.NETasp.net core 上使用redis探索(3)--redis示例demo

asp.net core 上使用redis探索(3)--redis示例demo

时间2023-12-03 03:16:03发布访客分类ASP.NET浏览631
导读:由于是基于.net-core平台,所以,我们最好是基于IDistributedCache接口来实现。ASP.NET-CORE下的官方redis客户端实现是基于StackExchange的。但是官方提供的IDistributeCache接口中...

由于是基于.net-core平台,所以,我们最好是基于IDistributedCache接口来实现。ASP.NET-CORE下的官方redis客户端实现是基于StackExchange的。但是官方提供的IDistributeCache接口中的方法只是增删改查,我们可以继续拓展,增加订阅/发布,消息队列,当然这些方法必须是基于底层的StackExchange相对应的方法来做的。 如果我们要实现自己的Redis客户端,同时不使用底层的StackExchange驱动,可以派生一个继承自IDistributedCache的接口,定义自己需要的方法,例如:

public interface IServiceStackRedisCache : IDistributedCache
{
    
    void DeleteT>
    (T item);
     // 删除
    void DeleteAllT>
    (T item);
    
    T GetT>
    (string id);
    
    IQueryableT>
     GetAllT>
    ();
    
    IQueryableT>
     GetAllT>
    (string hash, string value);
    
    IQueryableT>
     GetAllT>
    (string hash, string value, ExpressionFuncT, bool>
    >
     filter);
    
    long PublishMessage(string channel, object item);
    
    void SetT>
    (T item);
    
    void SetT>
    (T item, Liststring>
     hash, Liststring>
     value, string keyName);
    
    void SetT>
    (T item, string hash, string value, string keyName);
    
    void SetAllT>
    (ListT>
     listItems);
    
    void SetAllT>
    (ListT>
     list, Liststring>
     hash, Liststring>
     value, string keyName);
    
    void SetAllT>
    (ListT>
     list, string hash, string value, string keyName);

}
    

接口有了,接下来就是继承自接口的类,我们定义一个类来实现接口里的方法,例如:

using ServiceStack.Redis;


namespace Microsoft.Extensions.Caching.Redis
{

    public class ServiceStackRedisCache : IServiceStackRedisCache
    {
    
        private readonly IRedisClientsManager _redisManager;
    
        private readonly ServiceStackRedisCacheOptions _options;
    

        public ServiceStackRedisCache(IOptionsServiceStackRedisCacheOptions>
 optionsAccessor)
        {

            if (optionsAccessor == null)
            {
    
                throw new ArgumentNullException(nameof(optionsAccessor));

            }
    

            _options = optionsAccessor.Value;


            var host = $"{
_options.Password}
@{
_options.Host}
:{
_options.Port}
    ";
    
            RedisConfig.VerifyMasterConnections = false;
    
            _redisManager = new RedisManagerPool(host);

        }

        #region Base

        public byte[] Get(string key)
        {

            if (key == null)
            {
    
                throw new ArgumentNullException(nameof(key));

            }


            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {

                if (client.Exists(key) == 1)
                {
    
                    return client.Get(key);

                }

            }
    
            return null;

        }
    

        public async Taskbyte[]>
 GetAsync(string key)
        {
    
            return Get(key);

        }


        public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
        {

            if (key == null)
            {
    
                throw new ArgumentNullException(nameof(key));

            }


            if (value == null)
            {
    
                throw new ArgumentNullException(nameof(value));

            }


            if (options == null)
            {
    
                throw new ArgumentNullException(nameof(options));

            }


            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {
    
                var expireInSeconds = GetExpireInSeconds(options);
    
                if (expireInSeconds >
 0)
                {
    
                    client.SetEx(key, expireInSeconds, value);
    
                    client.SetEx(GetExpirationKey(key), expireInSeconds, Encoding.UTF8.GetBytes(expireInSeconds.ToString()));

                }

                else
                {
    
                    client.Set(key, value);

                }

            }

        }


        public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options)
        {
    
            Set(key, value, options);

        }


        public void Refresh(string key)
        {

            if (key == null)
            {
    
                throw new ArgumentNullException(nameof(key));

            }


            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {

                if (client.Exists(key) == 1)
                {
    
                    var value = client.Get(key);

                    if (value != null)
                    {
    
                        var expirationValue = client.Get(GetExpirationKey(key));

                        if (expirationValue != null)
                        {
    
                            client.Expire(key, int.Parse(Encoding.UTF8.GetString(expirationValue)));

                        }

                    }

                }

            }

        }


        public async Task RefreshAsync(string key)
        {

            if (key == null)
            {
    
                throw new ArgumentNullException(nameof(key));

            }
    

            Refresh(key);

        }


        public void Remove(string key)
        {

            if (key == null)
            {
    
                throw new ArgumentNullException(nameof(key));

            }


            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {
    
                client.Del(key);

            }

        }


        public async Task RemoveAsync(string key)
        {
    
            Remove(key);

        }


        private int GetExpireInSeconds(DistributedCacheEntryOptions options)
        {

            if (options.SlidingExpiration.HasValue)
            {
    
                return (int)options.SlidingExpiration.Value.TotalSeconds;

            }

            else if (options.AbsoluteExpiration.HasValue)
            {
    
                return (int)options.AbsoluteExpirationRelativeToNow.Value.TotalSeconds;

            }

            else
            {
    
                return 0;

            }

        }


        private string GetExpirationKey(string key)
        {

            return key + $"-{
nameof(DistributedCacheEntryOptions)}
    ";

        }
    
        #endregion
        #region data
        public T GetT>
(string id)
        {

            using (var redisClient = _redisManager.GetClient())
            {
    
                var redis = redisClient.AsT>
    ();
    
                return redis.GetById(id.ToLower());

            }

        }
    

        public IQueryableT>
     GetAllT>
()
        {

            using (var redisClient = _redisManager.GetClient())
            {
    
                var redis = redisClient.AsT>
    ();
    
                return redis.GetAll().AsQueryable();

            }

        }
    

        public IQueryableT>
     GetAllT>
    (string hash, string value, ExpressionFuncT, bool>
    >
 filter)
        {
    
            var filtered = _redisManager.GetClient().GetAllEntriesFromHash(hash).Where(c =>
     c.Value.Equals(value, StringComparison.CurrentCultureIgnoreCase));
    
            var ids = filtered.Select(c =>
     c.Key);
    

            var ret = _redisManager.GetClient().AsT>
    ().GetByIds(ids).AsQueryable()
                                .Where(filter);
    

            return ret;

        }
    

        public IQueryableT>
     GetAllT>
(string hash, string value)
        {
    
            var filtered = _redisManager.GetClient().GetAllEntriesFromHash(hash).Where(c =>
     c.Value.Equals(value, StringComparison.CurrentCultureIgnoreCase));
    
            var ids = filtered.Select(c =>
     c.Key);
    

            var ret = _redisManager.GetClient().AsT>
    ().GetByIds(ids).AsQueryable();
    
            return ret;

        }
    

        public void SetT>
(T item)
        {

            using (var redisClient = _redisManager.GetClient())
            {
    
                var redis = redisClient.AsT>
    ();
    
                redis.Store(item);

            }

        }
    

        public void SetT>
(T item, string hash, string value, string keyName)
        {
    
            Type t = item.GetType();
    
            PropertyInfo prop = t.GetProperty(keyName);
    

            _redisManager.GetClient().SetEntryInHash(hash, prop.GetValue(item).ToString(), value.ToLower());
    

            _redisManager.GetClient().AsT>
    ().Store(item);

        }
    

        public void SetT>
    (T item, Liststring>
     hash, Liststring>
 value, string keyName)
        {
    
            Type t = item.GetType();
    
            PropertyInfo prop = t.GetProperty(keyName);
    

            for (int i = 0;
     i  hash.Count;
 i++)
            {
    
                _redisManager.GetClient().SetEntryInHash(hash[i], prop.GetValue(item).ToString(), value[i].ToLower());

            }
    

            _redisManager.GetClient().AsT>
    ().Store(item);

        }
    

        public void SetAllT>
    (ListT>
 listItems)
        {

            using (var redisClient = _redisManager.GetClient())
            {
    
                var redis = redisClient.AsT>
    ();
    
                redis.StoreAll(listItems);

            }

        }
    

        public void SetAllT>
    (ListT>
 list, string hash, string value, string keyName)
        {

            foreach (var item in list)
            {
    
                Type t = item.GetType();
    
                PropertyInfo prop = t.GetProperty(keyName);
    

                _redisManager.GetClient().SetEntryInHash(hash, prop.GetValue(item).ToString(), value.ToLower());
    

                _redisManager.GetClient().AsT>
    ().StoreAll(list);

            }

        }
    

        public void SetAllT>
    (ListT>
     list, Liststring>
     hash, Liststring>
 value, string keyName)
        {

            foreach (var item in list)
            {
    
                Type t = item.GetType();
    
                PropertyInfo prop = t.GetProperty(keyName);
    

                for (int i = 0;
     i  hash.Count;
 i++)
                {
    
                    _redisManager.GetClient().SetEntryInHash(hash[i], prop.GetValue(item).ToString(), value[i].ToLower());

                }
    

                _redisManager.GetClient().AsT>
    ().StoreAll(list);

            }

        }
    

        public void DeleteT>
(T item)
        {

            using (var redisClient = _redisManager.GetClient())
            {
    
                var redis = redisClient.AsT>
    ();
    
                redis.Delete(item);

            }

        }
    

        public void DeleteAllT>
(T item)
        {

            using (var redisClient = _redisManager.GetClient())
            {
    
                var redis = redisClient.AsT>
    ();
    
                redis.DeleteAll();

            }

        }


        public long PublishMessage(string channel, object item)
        {
    
            var ret = _redisManager.GetClient().PublishMessage(channel, JsonConvert.SerializeObject(item));
    
            return ret;

        }


        #endregion
    }

}
    

在这里我们使用ServiceStack来作为底层redis驱动。在构造函数中根据配置连接redis服务器。

aps.net-core给我们提供了强大的配置功能,使用强类型的Options,一般,我们实现一个继承自IOptionsTOptions> 的类。定义一些字段用来表示主机,端口等常规redis配置选项。由于IOptions接口定义了一个Value属性,我们可以通过这个属性来获取配置类的实例。 然后我们在redis客户端类中(也就是上面的ServiceStackRedisCache类),使用构造函数注入。这样就能获取到redis的配置了。 然后我们在控制器的构造函数中注入redis客户端类实例:

private readonly IServiceStackRedisCache _cache;

public ValuesController(IServiceStackRedisCache cache)
{
    
    _cache = cache;

}
    

如此,我们才能使用redis客户端去操作redis服务器。 最后就是最重要的部分了。ASP.NET-CORE框架随处可见的都是依赖注入。上面所有的程序,都是一个接口对应着一个类。所谓的依赖注入,其实就是继承自接口的类的实例化过程,但是这个过程是解耦的!DI的作用主要就是用来解耦实例化的过程。 ASP.NET-CORE框架依赖注入部分是在ConfigureService中使用的。 从上面的过程中,我们看到有两个构造函数的注入过程,因此,我们需要实现两个DI,分别是配置类的DI和redis客户端类的DI。

services.Configure(setupAction);
    

services.Add(ServiceDescriptor.SingletonIServiceStackRedisCache, ServiceStackRedisCache>
    ());
    

整个步骤就是: 1.定义接口,用于继承IDistributedCache的接口。该接口主要封装了基本的redis操作。 2.实现接口,实现redis的各个逻辑。 3.基于IOptionsTOptions> 接口实现redis的常规配置。 4.在控制器的构造函数中注入。 5.依赖注入以上接口的实例。

完整demo下载:链接:https://pan.baidu.com/s/17w0c0y9_VF3TzvgilgazjQ 密码:4u5e

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: asp.net core 上使用redis探索(3)--redis示例demo
本文地址: https://pptw.com/jishu/565639.html
Unity容器在asp.net mvc中的IOC应用及AOP应用 asp.net core上使用Redis探索(2)

游客 回复需填写必要信息