第30章 分布式缓存强制删除触发器的触发调试

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1 Services.Users.Caching.RoleCacheEventConsumer

using Core.Caching;

using Core.Domain.Users;

using Services.Caching;

namespace Services.Users.Caching

{

    /// <summary>

    /// 摘要

    ///     通过该类中的方法成员在角色实体的1个实例执行插入、更新或持久化/逻辑删除操作后为该实体实例的分布式缓存的强制移除操作提供数据支撑从而为新变更的实例缓存操作预留出相应的内存空间。

    /// </summary>

    public class RoleCacheEventConsumer : CacheEventConsumer<Role>

    {

        /// <param name="entity">角色实体的1个指定实例。</param>

        /// <summary>

        /// 【异步清理缓存】

        /// <remarks>

        /// 摘要

        ///     执行插入、更新或删除操作时从分布式数据库中强制移除1个指定的缓存项(/(“JSON”编码格式的)值对)和字典实例中强制移除1个指定的键/值对。

        /// </remarks>

        /// </summary>

        protected override async Task ClearCacheAsync(Role entity)

        {

            await RemoveByPrefixAsync(EntityCacheDefaults<Role>.AllCacheKey.Key);

        }

    }

}

2 重构Framework.Infrastructure.DependencyInjectionStartup. ConfigureServices

  services.AddSingleton<IEventPublisher, EventPublisher>();

            var typeFinder = Singleton<ITypeFinder>.Instance;

            //通过反射方式把继承于“IConsumer<>”接口的所有具体实现类进行实例化后把这些实例注入到.Net(Core)内置容器中。

            var consumers = typeFinder.FindClassesOfType(typeof(IConsumer<>)).ToList();

            foreach (var consumer in consumers)

                foreach (var findInterface in consumer.FindInterfaces((type, criteria) =>

                {

                    var isMatch = type.IsGenericType && ((Type)criteria!).IsAssignableFrom(type.GetGenericTypeDefinition());

                    return isMatch;

                }, typeof(IConsumer<>)))

                    services.AddScoped(findInterface, consumer);

3 WebApi.Controllers.EventPublisherTestController

using Core.Caching;

using Core.Domain.Users;

using Core.Events;

using Data;

using LinqToDB;

using Microsoft.AspNetCore.Mvc;

using WebApi.Models;

namespace WebApi.Controllers

{

    [Route("[controller]/[action]")]

    [ApiController]

    public class EventPublisherTestController : ControllerBase

    {

        #region 拷贝构造方法与变量

        private readonly EFCoreContext _context;

        private readonly IStaticCacheManager _staticCacheManager;

        private readonly IEventPublisher _eventPublisher;

        public EventPublisherTestController(EFCoreContext context,

            IStaticCacheManager staticCacheManager,

            IEventPublisher eventPublisher)

        {

            _context = context;

            _staticCacheManager = staticCacheManager;

            _eventPublisher = eventPublisher;

        }

        #endregion

        [HttpGet]

        public async Task<MessageModel<bool>> EventPublisherTestAsync()

        {

            MessageModel<bool> _messageModel = new MessageModel<bool>();

            try

            {

                List<Role> _roleList = await _context.GetDbSet<Role>().ToListAsync();

                _staticCacheManager.PrepareKeyForDefaultCache(EntityCacheDefaults<Role>.AllCacheKey);

                await _staticCacheManager.SetAsync(_staticCacheManager.PrepareKeyForDefaultCache(EntityCacheDefaults<Role>.AllCacheKey), _roleList);

                Role _role = new Role() { Name = "EventPublisherTest", IsActive = true, Remark = "强制删除触发器的触发调试" };

                await _context.GetDbSet<Role>().AddAsync(_role);

                _context.SaveChanges();

                await _eventPublisher.EntityInsertedAsync(_role);

                _messageModel.Success = true;

                _messageModel.Message = "已经成功触发强制删除触发器";

                return _messageModel;

            }

            catch (Exception exception)

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "触发强制删除触发器失败"+ exception.Message;

                return _messageModel;

            }

        }

    }

}

4 对于分布式缓存强制移除泛型注销器定义的一些思考

1、到目前为止.Net(Core)7的内置依赖注入容器依然不能自动的把多泛型继承类进行实例化这是“CacheEventConsumer<TEntity>”类被定义为抽象类的原因也是继承于“IConsumer<>”接口的所有具体实现类必须通过反射方式进行实例化的原因。

    2、本人认为对“CacheEventConsumer<TEntity>”类进行继承从而实现多泛型继承类的实例化并不是一种最好的解决方案例如“RoleCacheEventConsumer”这样会增加程序定义实现的复杂性。

3、本人认为更好解决方案之一是

    3.1、直接把“CacheEventConsumer<TEntity>”类被定义为单泛型继承类。

    3.2、直接把“CacheEventConsumer<TEntity>”类被定义为具体实现(非抽象)类。

    3.3、删除例如“RoleCacheEventConsumer”这样的继承类。

    3.4、直接通过“CacheEventConsumer<TEntity>”类实现分布式缓存强制移除操作而非“RoleCacheEventConsumer”这样的继承类。

4、本人认为更好解决方案之二是

    4.1、通过第3方依赖注入容器“Autofac.Extensions.DependencyInjection”据说该依赖注入容器能够自动的把多泛型继承类进行实例化。

    4.2、直接把“CacheEventConsumer<TEntity>”类被定义为具体实现(非抽象)类。

    4.3、删除例如“RoleCacheEventConsumer”这样的继承类。

    4.4、直接通过“CacheEventConsumer<TEntity>”类实现分布式缓存强制移除操作而非“RoleCacheEventConsumer”这样的继承类。

    以上两种方案都是一种解决思路没有经过测试如果有时间本人会重点以第一种思路方案对分布式缓存强制移除泛型注销器定义实现进行重构

对以上功能更为具体实现和注释见230203_024shopDemo(分布式缓存强制删除触发器的触发调试)。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6