资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

第17章 注销器的泛型实现

Java 更新时间: 发布时间: 计算机考试归档 最新发布

第17章 注销器的泛型实现

nopCommerce程序中以泛型形式对注销器进行了定义,以实现在实体实例发生改变,以泛型方法来删除Redis中的缓存的1个指定实体的所有实例及其键之后, 重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

1 重构Program.cs

//把继承于“IConsumer<>”泛型接口的所有具体实现类的实例,依赖注入到.Net(Core)6框架内置容器中。

//获取所有继承于“IConsumer<>”泛型接口的所有具体实现类的类型实例。

var _consumerList = AppDomain.CurrentDomain.GetAssemblies()

    .SelectMany(a => a.GetTypes().Where(t => typeof(IConsumer<>).DoesTypeImplementOpenGeneric(t) && !t.IsAbstract))

    .ToList();

2 触发器泛型扩展(EventPublisherExtensions)实现

2.1 EntityInsertedEvent

  /// 泛型类型实例(这里特指:1个指定实体的类型实例)。

    ///

    /// 【触发实体插入--类】

    /// 摘要:

    ///     在1个指定实体的1个指定实例的对数据库中指定表的“插入”操作完成后,通过触发器(EventPublisher)实例,以该类的实例作为参数实例,来调用泛型注销器具体实现类中的方法(HandleEventAsync),来删除Redis中的缓存的指定实体的所有实例及其键之后,

    /// 重新把数据库中指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    ///

    public class EntityInsertedEvent

    {

        #region 拷贝构造方法

        /// 1个指定实体的1个指定实例。

        ///

        /// 【拷贝构造方法】

        ///

        ///

        /// 摘要:

        ///     通过该构造方法中的参数实例,来实例化该类中的同类型属性成员。

        ///

        public EntityInsertedEvent(T entity)

        {

            Entity = entity;

        }

        #endregion

        #region 属性

        ///

        /// 【单个实体】

        ///

        /// 摘要:

        ///     获取/设置1个指定实体的1个指定实例。

        /// 注意:

        ///     把该属性成员命名为:Instance/EntityInstance更为合适。

        ///

        ///

        public T Entity { get; }

        #endregion

    }

2.2 EntityUpdatedEvent

/// 泛型类型实例(这里特指:1个指定实体的类型实例)。

    ///

    /// 【触发实体更新--类】

    /// 摘要:

    ///     在1个指定实体的1个指定实例的对数据库中指定表的“更新”操作完成后,通过触发器(EventPublisher)实例,以该类的实例作为参数实例,来调用泛型注销器具体实现类中的方法(HandleEventAsync),来删除Redis中的缓存的指定实体的所有实例及其键之后,

    /// 重新把数据库中指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    ///

    public class EntityUpdatedEvent

    {

        #region 拷贝构造方法

        /// 1个指定实体的1个指定实例。

        ///

        /// 【拷贝构造方法】

        ///

        ///

        /// 摘要:

        ///     通过该构造方法中的参数实例,来实例化该类中的同类型属性成员。

        ///

        public EntityUpdatedEvent(T entity)

        {

            Entity = entity;

        }

        #endregion

        #region 属性

        ///

        /// 【单个实体】

        ///

        /// 摘要:

        ///     获取/设置1个指定实体的1个指定实例。

        /// 注意:

        ///     把该属性成员命名为:Instance/EntityInstance更为合适。

        ///

        ///

        public T Entity { get; }

        #endregion

    }

2.3 EntityDeletedEvent

/// 泛型类型实例(这里特指:1个指定实体的类型实例)。

    ///

    /// 【触发实体删除--类】

    /// 摘要:

    ///     在1个指定实体的1个指定实例的对数据库中指定表的“删除”操作完成后,通过触发器(EventPublisher)实例,以该类的实例作为参数实例,来调用泛型注销器具体实现类中的方法(HandleEventAsync),来删除Redis中的缓存的指定实体的所有实例及其键之后,

    /// 重新把数据库中指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    ///

    public class EntityDeletedEvent

    {

        #region 拷贝构造方法

        /// 1个指定实体的1个指定实例。

        ///

        /// 【拷贝构造方法】

        ///

        ///

        /// 摘要:

        ///     通过该构造方法中的参数实例,来实例化该类中的同类型属性成员。

        ///

        public EntityDeletedEvent(T entity)

        {

            Entity = entity;

        }

        #endregion

        #region 属性

        ///

        /// 【单个实体】

        ///

        /// 摘要:

        ///     获取/设置1个指定实体的1个指定实例。

        /// 注意:

        ///     把该属性成员命名为:Instance/EntityInstance更为合适。

        ///

        ///

        public T Entity { get; }

        #endregion

    }

2.4 EventPublisherExtensions

namespace Linkage.Events

{

    ///

    /// 【触发器扩展】

    ///

    ///

    /// 摘要:

    ///     该类中的方法通过泛型操作,在1个指定实体的1个指定实例的对数据库中指定表的“插入”/“更新”/“删除”操作完成之后,获取该指定实体实例;将当前类中的指定方法通过触发器(EventPublisher)实例及其指定实体实例参数,

    /// 来删除Redis中的缓存的1个指定实体的所有实例及其键之后, 重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    ///

    public static class EventPublisherExtensions

     {

        #region 方法

        /// 泛型类型实例(这里特指:1个指定实体的类型实例)。

        /// 触发器(EventPublisher)实例。

        /// 1个指定实体的1个指定实例。

        ///

        /// 【异步触发实体插入】

        ///

        /// 摘要:

        ///      在1个指定实体的1个指定实例的对数据库中指定表的“插入”操作完成后,操作完成之后,获取该指定实体实例;当前方法通过触发器(EventPublisher)实例及其指定实体实例参数,来删除Redis中的缓存的1个指定实体的所有实例及其键之后,

        /// 重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        ///

        ///

        public static async Task EntityInsertedAsync(this IEventPublisher eventPublisher, T entity)

        {

            await eventPublisher.PublishAsync(new EntityInsertedEvent(entity));

        }

        /// 泛型类型实例(这里特指:1个指定实体的类型实例)。

        /// 触发器(EventPublisher)实例。

        /// 1个指定实体的1个指定实例。

        ///

        /// 【异步触发实体更新】

        ///

        /// 摘要:

        ///     在1个指定实体的1个指定实例的对数据库中指定表的“更新”操作完成后,获取该指定实体实例;当前方法通过触发器(EventPublisher)实例及其指定实体实例参数,来删除Redis中的缓存的1个指定实体的所有实例及其键之后,

        /// 重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        ///

        ///

        public static async Task EntityUpdatedAsync(this IEventPublisher eventPublisher, T entity)

        {

            await eventPublisher.PublishAsync(new EntityUpdatedEvent(entity));

        }

        /// 泛型类型实例(这里特指:1个指定实体的类型实例)。

        /// 触发器(EventPublisher)实例。

        /// 1个指定实体的1个指定实例。

        ///

        /// 【异步触发实体删除】

        ///

        /// 摘要:

        ///       在1个指定实体的1个指定实例的对数据库中指定表的“删除”操作完成后,获取该指定实体实例;当前方法通过触发器(EventPublisher)实例及其指定实体实例参数,来删除Redis中的缓存的1个指定实体的所有实例及其键之后,

        /// 重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        ///

        ///

        public static async Task EntityDeletedAsync(this IEventPublisher eventPublisher, T entity)

        {

            await eventPublisher.PublishAsync(new EntityDeletedEvent(entity));

        }

        #endregion

    }

}

3 注销器的泛型实现

3.1 泛型抽象注销器类: CacheEventConsumer

    注意:

    由于.Net(Core)6框架,不能以反射方式实例化泛型类:“CacheEventConsumer”,并依赖注入到.Net(Core)6框架的内置容器中,所以把“CacheEventConsumer”类定义为了“抽象”类,以供能够以反射方式实例化类进行继承。

using Linkage.Events;

using Linkage.Extensions;

using Microsoft.Extensions.Caching.Distributed;

namespace Linkage.Caching

{

    /// 泛型类型实例(这里特指:1个指定实体的类型实例)。

    ///

    /// 【泛型抽象注销器--类】

    ///

    /// 摘要:

    ///    在1个指定实体的1个指定实例的对数据库中指定表的“插入”/“更新”/“删除”操作完成后,通过触发器实例,调用当前抽象类中的指定方法,来删除Redis中的1个指定实体的所有实例及其键之后,

    /// 重新把数据库中1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    /// 注意:

    ///     由于.Net(Core)6框架,不能以反射方式实例化泛型类:“CacheEventConsumer”,并依赖注入到.Net(Core)6框架的内置容器中,所以把“CacheEventConsumer”类定义为了“抽象”类,以供能够以反射方式实例化类进行继承。

    ///

    ///

    public abstract partial class CacheEventConsumer :

        IConsumer>,

        IConsumer>,

        IConsumer>

    {

        #region 变量--拷贝构造方法

        private readonly IDistributedCache _distributedCache;

        public CacheEventConsumer()

        {

            _distributedCache = ServiceProviderExtension.ServiceProvider.GetService();

        }

        #endregion

        #region 方法--私有/保护

        /// 1指定实体的1个实例。

        ///

        /// 【异步清理缓存】

        ///

        /// 摘要:

        ///     当1个指定实体的1个指定实例,通过异步方法把Redis中的缓存数据被删除成功完成后,返回该异步方法的“完成”执行状态。

        ///

        ///

        protected virtual Task ClearCacheAsync(TEntity entity)

        {

            return Task.CompletedTask;

        }

        /// 1个指定实体的1个指定实例。

        /// 实体触发枚举的1个指定实例。

        ///

        /// 【异步触发句柄】

        ///

        /// 摘要:

        ///      在执行省/直辖市的插入操作之后,通过触发器实例,调用当前方法,来删除Redis中的缓存的省/直辖市的所有实例及其键之后,

        /// 重新把数据库中省/直辖市所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        /// 注意:

        ///     为了更加直观,把该方法定义为了特定实现。

        ///

        ///

        protected virtual async Task ClearCacheAsync(TEntity entity, EntityEventType entityEventType)

        {

            await _distributedCache.RemoveAsync("StateAll");

            await ClearCacheAsync(entity);

        }

        #endregion

        #region 方法

        /// 触发实体更新(EntityInsertedEvent)类的1个指定实例。

        ///

        /// 【异步触发句柄】

        ///

        /// 摘要:

        ///    在1个指定实体的1个指定实例的对数据库中指定表的“插入”操作完成后,通过触发器实例,调用当前方法,来删除Redis中的1个指定实体的所有实例及其键之后,

        /// 重新把数据库中1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        ///

        ///

        public virtual async Task HandleEventAsync(EntityInsertedEvent eventMessage)

        {

            await ClearCacheAsync(eventMessage.Entity, EntityEventType.Insert);

        }

        /// 触发实体更新(EntityUpdatedEvent)类的1个指定实例。

        ///

        /// 【异步触发句柄】

        ///

        /// 摘要:

        ///    在1个指定实体的1个指定实例的对数据库中指定表的“更新”操作完成后,通过触发器实例,调用当前方法,来删除Redis中的1个指定实体的所有实例及其键之后,

        /// 重新把数据库中1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        ///

        ///

        public virtual async Task HandleEventAsync(EntityUpdatedEvent eventMessage)

        {

            await ClearCacheAsync(eventMessage.Entity, EntityEventType.Update);

        }

        /// 触发实体删除(EntityDeletedEvent)类的1个指定实例。

        ///

        /// 【异步触发句柄】

        ///

        /// 摘要:

        ///    在1个指定实体的1个指定实例的对数据库中指定表的“删除”操作完成后,通过触发器实例,调用当前方法,来删除Redis中的1个指定实体的所有实例及其键之后,

        /// 重新把数据库中1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

        ///

        ///

        public virtual async Task HandleEventAsync(EntityDeletedEvent eventMessage)

        {

            await ClearCacheAsync(eventMessage.Entity, EntityEventType.Delete);

        }

        #endregion

        #region 嵌套枚举

        ///

        /// 【实体触发--枚举】

        ///

        /// 摘要:

        ///     通过该枚举中的1个成员实例,获取泛型“注销器”中的1个指定(“插入”/“更新”/“删除”)方法,来移除缓存中指定实体的所有数据。

        ///

        ///

        protected enum EntityEventType

        {

            ///

            /// 【插入】

            ///

            /// 摘要:

            ///    在1个指定实体的1个指定实例的对数据库中指定表的“插入”操作完成后,由“触发器”调用当前的泛型“注销器”中的指定(“插入”)方法,来移除缓存中指定实体的所有实例。

            ///

            ///

            Insert,

            ///

            /// 【更新】

            ///

            /// 摘要:

            ///   在1个指定实体的1个指定实例的对数据库中指定表的“更新”操作完成后,由“触发器”调用当前的泛型“注销器”中的指定(“更新”)方法,来移除缓存中指定实体的所有实例。

            ///

            ///

            Update,

            ///

            /// 【删除】

            ///

            /// 摘要:

            ///   在1个指定实体的1个指定实例的对数据库中指定表的“删除”操作完成后,由“触发器”调用当前的泛型“注销器”中的指定(“删除”)方法,来移除缓存中指定实体的所有实例。

            ///

            ///

            Delete

        }

        #endregion

    }

}

3.2泛型注销器的具体实现类: StateOpenTypeConsumer

    注意:

    由于泛型类:“CacheEventConsumer”,不能以反射方式实例化,并依赖注入到.Net(Core)6框架的内置容器中,所以通过“StateOpenTypeConsumer”类对“CacheEventConsumer”类的继承,把“StateOpenTypeConsumer”类以反射方式实例化后,依赖注入到.Net(Core)6框架的内置容器中。从而达到通过“StateOpenTypeConsumer”类的实例,调用“CacheEventConsumer”类中的指定方法,来删除Redis中的缓存的1个指定实体的所有实例及其键之后,重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

using Linkage.Domain.Directory;

namespace Linkage.Caching

{

    ///

    /// 【省/直辖市抽象注销器--类】

    ///

    /// 摘要:

    ///    在1个指定实体的1个指定实例的对数据库中指定表的“插入”/“更新”/“删除”操作完成后,通过触发器实例,调用基类类中的指定方法,来删除Redis中的1个指定实体的所有实例及其键之后,

    /// 重新把数据库中1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    /// 注意:

    ///    1、由于泛型类:“CacheEventConsumer”,不能以反射方式实例化,并依赖注入到.Net(Core)6框架的内置容器中,所以通过“StateOpenTypeConsumer”类对“CacheEventConsumer”类的继承,

    /// 把“StateOpenTypeConsumer”类以反射方式实例化后,依赖注入到.Net(Core)6框架的内置容器中。从而达到通过“StateOpenTypeConsumer”类的实例,调用“CacheEventConsumer”类中的指定方法,

    /// 来删除Redis中的缓存的1个指定实体的所有实例及其键之后,重新把1个指定实体所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

    ///    2、当然当前类也可以通过对所继承抽象类“CacheEventConsumer”中方法(包含私有方法)的覆写,来实现对Redis中的1个指定实体的所有实例及其键的删除操作,当前为了简化实现,只用于当前类的实例,

    ///  其具体的缓存数据的删除操作是通过当前类的实例,调用所继承抽象类“CacheEventConsumer”中的指定方法实现的。

    ///

    ///

    public partial class StateOpenTypeConsumer : CacheEventConsumer

    {

    }

}

4重构 CachingConsumerController和CachingConsumerIndex.cshtml

4.1 重构CachingConsumerController

  [HttpPost]

        public async Task OptenTypeRenderjax(StateModel stateModel)

        {

            State _state = new State();

            _state.Name = stateModel.Name;

            await _context.StateDbSet.AddAsync(_state);

            await _context.SaveChangesAsync();

            //以泛型操作,通过触发器实例,来删除Redis中的缓存的省/直辖市的所有实例及其键之后,

            //重新把数据库中省/直辖市所有数据更新加载到Redis的缓存中,从而达到立即把最新的数据在页面上进行渲染显示的目的。

            await _eventPublisher.EntityInsertedAsync(_state);

            return Json(true);

        }

4.2 重构CachingConsumerIndex.cshtml

  // 页面在【添加后立即】渲染显示添加数据(泛型实现)

        $("#OptenTypeRender").on("click", function () {

            if ($("#Name").val() == "" || $("#Name").val() == null) {

                alert("省/直辖市不能为空!");

                return;

            }

            $.ajax({

                url: "/CachingConsumer/OptenTypeRenderjax",

                type: "POST",

                datatype: "JSON",

                cache: false,  //禁用缓存。

                data: $("#AddState").serialize(),

                success: function (data) {

                    window.location.href = "/CachingConsumer/Index";

                }

            });

        });

对以上功能更为具体实现和注释见:221029_17Linkage(注销器的泛型实现)。

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/1043986.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【第17章 注销器的泛型实现】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2