zoukankan      html  css  js  c++  java
  • ABP框架

    出处:http://www.cnblogs.com/kid1412/p/5987083.html

    文档目录

    本节内容:

    简介

    ABP提供了一个缓存接口,它内部使用了这个缓存接口。虽然接口的默认实现是MemoryCache,但可以用任何其它实现的缓存供应器。Abp.RedisCache包用Redis实现了缓存(查看下方的“Redis 缓存集成”)。

    ICacheManager

    缓存的主要接口是ICacheManager。我们可以注入它并用它获取一个缓存,如:

    复制代码
    public class TestAppService : ApplicationService
    {
        private readonly ICacheManager _cacheManager;
    
        public TestAppService(ICacheManager cacheManager)
        {
            _cacheManager = cacheManager;
        }
    
        public Item GetItem(int id)
        {
            //Try to get from cache
            return _cacheManager
                    .GetCache("MyCache")
                    .Get(id.ToString(), () => GetFromDatabase(id)) as Item;
        }
    
        public Item GetFromDatabase(int id)
        {
            //... retrieve item from database
        }
    }
    复制代码

    在此例里,我们注入了ICacheManager,并获得一个名为MyCache的缓存。

    警告:GetCache方法

    如果你的类不是单例,不要在你构造器里使用GetCache,否则可能会销毁你的缓存。

    ICache

    ICacheManager.GetCache方法返回一个ICache。一个缓存是单例的(每个缓存名)。第一次请求时创建,然后一直返回同一个缓存对象。所以,我们可以在不同的类(客户端)里用相同的名字共享同一个缓存。

    在示例代码里,我们看到了ICache.get方法的简单使用。它有两个参数:

    key:字符串,必需,一个缓存项的键。

    factory:一个action(行为),在找不到指定key的缓存项时调用,Factory方法应该创建并返回切实的项,如果指定key的缓存已存在,就不调用。

    ICache接口也有如GetOrDefault、Set、Remove和Clear等方法。同样也有async版本。

    ITypedCache

    ICache接口以字符串为key,值是object类型。ITypedCache包装了ICache并提供了类型安全、泛型。我们可用泛型的GetCache扩展方法,获取一个ITypedCache:

    ITypedCache<int, Item> myCache = _cacheManager.GetCache<int, Item>("MyCache");

    同样,我们也可用AsTyped扩展方法,把一个已存在的ICache实例转换成ITypedCache。

    配置

    默认缓存超时是60分钟,它可以改。如果你超过60分钟没有使用缓存中的项,会从缓存中自动移除。你可以配置指定的缓存或是全部的缓存。

    复制代码
    //Configuration for all caches
    Configuration.Caching.ConfigureAll(cache =>
    {
        cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2);
    });
    
    //Configuration for a specific cache
    Configuration.Caching.Configure("MyCache", cache =>
    {
        cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8);
    });
    复制代码

    这段代码应该写在你模块的PreInitialize方法里,用这段代码,MyCache将有8个小时的超时时间,其它的缓存有2个小时。

    在第一次创建缓存(在第一次请求)调用你的配置行为。配置不是只有DefaultSlidingExpireTime,由于缓存对象是一个ICache,所以你可以用它的属性和方法,自由的配置和初始化。

    实体缓存

    虽然ABP缓存系统出于普通的目的,但有一个EntityCache基类,可帮你缓存实体。如果我们通过它们的Id获取的实体,我们可以用这个基类缓存它们,就不用再频繁地从数据库查询。假设我们有如下所示的一个person实体:

    复制代码
    public class Person : Entity
    {
        public string Name { get; set; }
    
        public int Age { get; set; }
    }
    复制代码

    并假设我们已经知道Id,要频繁地获取Name。首先,我们需要创建一个类来缓存项:

    [AutoMapFrom(typeof(Person))]
    public class PersonCacheItem
    {
        public string Name { get; set; }
    }

    我们不应该直接在缓存里存储实体,由于缓存可能需要序列化缓存对象,而实体不一定能序列化(尤其有导航属性的实体)。这就是为什么我们创建一个简单(像DTO:数据传输对象)类存储数据。添加AutoMapFrom特性,它可以自动地把Person转换成PersonCacheItem对象。如果我们不使用AutoMapFrom,我们应该为重载EntityCache类的MapToCacheItem方法,手动转换/映射。

    虽然不是必需,但我们可能想为我们的缓存类定义一个接口:

    public interface IPersonCache : IEntityCache<PersonCacheItem>
    {
    
    }

    最后,我们可以为实体创建缓存类:

    复制代码
    public class PersonCache : EntityCache<Person, PersonCacheItem>, IPersonCache, ITransientDependency
    {
        public PersonCache(ICacheManager cacheManager, IRepository<Person> repository)
            : base(cacheManager, repository)
        {
    
        }
    }
    复制代码

    这就是全部代码,我们的Person缓存已经可用。缓存类可以是暂时的(如示例)或单体的,这不是说缓存的数据是暂时的,它始终在你的应用里是全局的并线程安全的。

    现在,任何需要Person的Name时,我们可以通过person的Id从缓存获取,使用Person缓存的示例如下:

    复制代码
    public class MyPersonService : ITransientDependency
    {
        private readonly IPersonCache _personCache;
    
        public MyPersonService(IPersonCache personCache)
        {
            _personCache = personCache;
        }
    
        public string GetPersonNameById(int id)
        {
            return _personCache[id].Name; //alternative: _personCache.Get(id).Name;
        }
    }
    复制代码

    我们简单地注入IPersonCache,获取缓存项和获取Name属性。

    EntityCache 是如何工作

    • 在第一个调用里获取从仓储(从数据库)获取实体,然后在接下来的调用里从缓存里获取。
    •  如果实体更新或删除后,它自动使缓存失效,所以它将在下一个调用里重新从数据库获取。
    • 使用IObjectMapper映射到缓存项,AutoMpper模块实现了IObjectMapper,所以需要AutoMapper模块。你可以重载MapToCacheItem方法,手动映射实体到缓存项。
    • 使用缓存类全名作为缓存时的名称,你可以通过传递一个缓存名给基构造器来改变它。
    • 是线程安全的。

    如果你需要更复杂的缓存技术,你可以扩展EntityCache或创建你自己的解决方案。

    Redis 缓存集成

    默认缓存管理使用的是内存缓存。所以,如果你有多个并发的Web服务器使用同个应用,可能会成为一个问题,在这种情况下,你需要一个分布/集中缓存服务,你就可以简单的使用Redis做为你的缓存服务器。

    首先,你要在你的应用里,安装Abp.RedisCache的Nuget包(例如,你可在你的Web项目里安装)。接着为AbpRedisCacheModule添加DependsOn特性,然后在你模块预初始化方法里调用useRedis扩展方法。如下所示:

    复制代码
    //...other namespaces
    using Abp.Runtime.Caching.Redis;
    
    namespace MyProject.AbpZeroTemplate.Web
    {
        [DependsOn(
            //...other module dependencies
            typeof(AbpRedisCacheModule))]
        public class MyProjectWebModule : AbpModule
        {
            public override void PreInitialize()
            {
                //...other configurations
                
                Configuration.Caching.UseRedis();
            }
            
            //...other code
        }
    }
    复制代码

    Abp.RedisCache包使用”localhost“作为默认连接字符串,你可以在配置文件里添加连接字符串重写它,例如:

    <add name="Abp.Redis.Cache" connectionString="localhost"/>

    同样,你可以向appSettings里添加Redis的数据库Id,例如:

    <add key="Abp.Redis.Cache.DatabaseId" value="2"/>

    不同的数据库Id,在同一服务器上,帮助创建不同的键空间(独立缓存)。

    UseRedis方法也有一个重载,用给定的action(行为)直接设置选项值(在配置文件中重写)。

    查看更多有关Redis信息及它的配置,请查阅Redis文档

    提醒:Redis服务器应该安装和运行在ABP里。

    kid1412声明:转载请把此段声明完整地置于文章页面明显处,并保留个人在博客园的链接:http://www.cnblogs.com/kid1412/(可点击跳转)。

  • 相关阅读:
    MySQL学习——SQL查询语句(连接查询&子查询)(三)
    MySQL学习——SQL查询语句(使用集合函数查询)(二)
    MySQL学习——SQL查询语句(一)
    MySQL学习——操作数据库(增删改查)(二)
    MySQL学习——操作数据库(增删改查)(一)
    MySQL学习——MySQL数据库概述与基础
    Python学习之——Http协议简介
    Python学习之——Socket套接字(UDP连接)
    第04组 Beta版本演示
    第04组 Beta冲刺(4/5)
  • 原文地址:https://www.cnblogs.com/smileberry/p/7767072.html
Copyright © 2011-2022 走看看