• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
adow
博客园    首页    新随笔    联系   管理    订阅  订阅
当我在扩展ICacheManager时遇到的诡异情况
我看到entlib4.0中说可以通过继承ICacheManager来实现自己的cachemanager,我就想着该如何把其他的缓存工具集成到这里面来,我使用的是indeXus.Net Shared Cache (http://www.codeplex.com/SharedCache)。
这个问题我搞了一晚上都没有明白,所以贴出来想请大家看看是什么原因。如果管理员觉得不适合放置在首页请移走,很抱歉。

我看到entlib4.0中说可以通过继承ICacheManager来实现自己的cachemanager,我就想着该如何把其他的缓存工具集成到这里面来,我使用的是indeXus.Net Shared Cache (http://www.codeplex.com/SharedCache)。

我看了帮助文档,上面写只要继承ICacheManager和使用[ConfigurationElementTypeAttribute(typeof(CustomCacheManagerData))]属性标签,所以我很快就写了一个自己的CacheManager (其中很多代码来自一篇codeplex上的帖子,他没有包含标签的使用,地址忘记了)

Code
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Data;
  6using System.Web;
  7using System.IO;
  8using Microsoft.Practices.EnterpriseLibrary.Caching;
  9using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
 10using MergeSystem.Indexus.WinServiceCommon;
 11using MergeSystem.Indexus;
 12using MergeSystem.Indexus.WinServiceCommon.Provider.Cache;
 13using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
 14using Microsoft.Practices.EnterpriseLibrary.Caching.Configuration;
 15
 16namespace adow.shirecache.cachemanager
 17{
 18    /**//// <summary>
 19    /// 继承自ICacheManager,实现Indexus的CacheManager封装
 20    /// </summary>

 21    [ConfigurationElementTypeAttribute(typeof(CustomCacheManagerData))]
 22    //[ConfigurationElementType()]
 23    public class ShireCacheManagerIndexus : ICacheManager, IDisposable
 24    {
 25        private Microsoft.Practices.EnterpriseLibrary.Caching.Cache realCache;
 26        private BackgroundScheduler scheduler;
 27        private ExpirationPollTimer pollTimer;
 28
 29        public ShireCacheManagerIndexus()
 30        {
 31
 32        }

 33        //public ShireCacheManagerIndexus(Microsoft.Practices.EnterpriseLibrary.Caching.Cache realCache,
 34        //    BackgroundScheduler scheduler, ExpirationPollTimer pollTimer)
 35        //{
 36        //    this.realCache = realCache;
 37        //    this.scheduler = scheduler;
 38        //    this.pollTimer = pollTimer;
 39        //}
 40        public void Add(string key, object value, 
 41            CacheItemPriority scavengingPriority, ICacheItemRefreshAction refreshAction,
 42            params ICacheItemExpiration[] expirations)
 43        {
 44            IndexusDistributionCache.SharedCache.Add(key, value, GetAbsoluteTimeExpiration(expirations),
 45                GetCacheItemPriority(scavengingPriority));
 46            //IndexusDistributionCache.SharedCache.Add(key, value);
 47        }

 48
 49        public void Add(string key, object value)
 50        {
 51            IndexusDistributionCache.SharedCache.Add(key, value);
 52            
 53        }

 54
 55        public bool Contains(string key)
 56        {
 57            IList<string> allkeys = IndexusDistributionCache.SharedCache.GetAllKeys();
 58            if (allkeys != null)
 59                return allkeys.Contains<string>(key);
 60            else
 61                return false;
 62        }

 63
 64        public int Count
 65        {
 66            get
 67            {
 68                long total=IndexusDistributionCache.SharedCache.Count;
 69                if (total > Int32.MaxValue)
 70                    throw new Exception("超出Int32最大值了");
 71                else
 72                    return (int)total;
 73            }

 74        }

 75
 76        public void Flush()
 77        {
 78            IndexusDistributionCache.SharedCache.Clear();
 79        }

 80
 81        public object GetData(string key)
 82        {
 83            return IndexusDistributionCache.SharedCache.Get(key);
 84        }

 85
 86        public void Remove(string key)
 87        {
 88            IndexusDistributionCache.SharedCache.Remove(key);
 89        }

 90
 91        public object this[string key]
 92        {
 93            get
 94            {
 95                return this.GetData(key);
 96            }

 97        }

 98
 99        /**//// <summary>
100        /// 将IndexusMessage.CacheItemPriority 转换到 Microsoft.Practices.EnterpriseLibrary.Caching.CacheItemPriority
101        /// </summary>
102        /// <param name="scavengingPriority"></param>
103        /// <returns></returns>

104        private static IndexusMessage.CacheItemPriority GetCacheItemPriority(CacheItemPriority scavengingPriority)
105        {
106            switch (scavengingPriority)
107            {
108                // TODO validate these mappings
109                case CacheItemPriority.NotRemovable: return IndexusMessage.CacheItemPriority.High;
110                case CacheItemPriority.High: return IndexusMessage.CacheItemPriority.AboveNormal;
111                case CacheItemPriority.Normal: return IndexusMessage.CacheItemPriority.Normal;
112                case CacheItemPriority.Low: return IndexusMessage.CacheItemPriority.BelowNormal;
113                case CacheItemPriority.None: return IndexusMessage.CacheItemPriority.Low;
114            }

115            return IndexusMessage.CacheItemPriority.Normal;
116        }

117        /**//// <summary>
118        /// 将enterprise libraray 的过期时间转换到 标准时间
119        /// 只能转换绝对时间
120        /// </summary>
121        /// <param name="expirations"></param>
122        /// <returns></returns>

123        private static DateTime GetAbsoluteTimeExpiration(ICacheItemExpiration[] expirations)
124        {
125            if (expirations != null)
126            {
127                foreach (ICacheItemExpiration expiration in expirations)
128                {
129                    AbsoluteTime absoluteTimeExpiration = expiration as AbsoluteTime;
130                    if (absoluteTimeExpiration != null)
131                        return absoluteTimeExpiration.AbsoluteExpirationTime;
132                }

133            }

134            return DateTime.MinValue;
135        }

136
137        public void Dispose()
138        {
139            GC.SuppressFinalize(this);
140        }

141    }

142}



我对indexus的调用方法进行了测试,所以访问indexus的代码应该是正确的。
下面我将这个类配置到entlib cache中,配置文件:

Code
 1<?xml version="1.0" encoding="utf-8" ?>
 2<configuration>
 3    <configSections>
 4        <section name="cachingConfiguration" 
 5            type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
 6        <!--indexus缓存-->
 7        <section name="indexusNetSharedCache" 
 8            type="MergeSystem.Indexus.WinServiceCommon.Configuration.Client.IndexusProviderSection, MergeSystem.Indexus.WinServiceCommon"/>   
 9    </configSections>
10    <appSettings>
11        <add key="cache_root" value="E:\shirecachestore"/>
12        <add key="cache_write_key_table" value="1"/>
13    </appSettings>
14    <cachingConfiguration defaultCacheManager="SimpleCacheManager">
15        <cacheManagers>
16            <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"
17              numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
18              type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
19              name="SimpleCacheManager" />
20            <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"
21                numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
22                type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
23                name="LocalCacheManager" />
24            <!--使用indexus缓存管理器-->
25            <add type="adow.shirecache.cachemanager.ShireCacheManagerIndexus, adow.shirecache.cachemanager"
26               name="IndexusCacheManager" />
27        </cacheManagers>
28        <backingStores>
29            <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
30              name="Null Storage" />
31        </backingStores>
32    </cachingConfiguration>
33    <!--indexus缓存-->
34    <indexusNetSharedCache defaultProvider="IndexusSharedCacheProvider">
35        <servers>
36            <add key="adow-cache-server"  ipaddress="127.0.0.1" port="48888" />
37        </servers>
38        <providers>
39            <add
40              name="IndexusSharedCacheProvider"
41              type="MergeSystem.Indexus.WinServiceCommon.Provider.Cache.IndexusSharedCacheProvider, MergeSystem.Indexus.WinServiceCommon">
42            </add>
43        </providers>
44    </indexusNetSharedCache>
45</configuration>

我通过indexus的测试程序测试,确保indexus是在正确的运行中,下面开始使用cache,但是在构造对应的CacheManager时发生了错误,我们的常见的代码开始时这样:

Code
ICacheManager manager = null;
if (cachename != null && !cachename.Equals(""))
            {
                
manager = CacheFactory.GetCacheManager(cachename);
            }
            
else
            {
                
manager = CacheFactory.GetCacheManager();
            }
这时遇到了一个异常:
Test method adow.shirecache.test.UnitTest1.TestGetCache threw exception:  Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Caching.ICacheManager, IndexusCacheManager]) failed: 未找到类型“adow.shirecache.cachemanager.ShireCacheManagerIndexus”上的构造函数。 (Strategy type Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy, index 2) --->  System.MissingMethodException: 未找到类型“adow.shirecache.cachemanager.ShireCacheManagerIndexus”上的构造函数。

说没有构造函数,但是我明明写了一个不带参数的构造函数,(还复制了一个CacheManager的构造写法)。如果我使用默认的cachename是没有问题的。

然后我不使用CacheFactory,而是直接创建
manager = new adow.shirecache.cachemanager.ShireCacheManagerIndexus();
是正常的,后面的操作也没有问题。

我用unity的方式来构造也没有问题:

Code
1IUnityContainer container = new UnityContainer();
2container.RegisterType<ICacheManager,ShireCacheManagerIndexus>("indexus");
3manager = container.Resolve<ICacheManager>("indexus");

问题是后两种都忽略了配置文件的存在,手工来创建cachemanager,没有实际意义。
然而,为什么我在使用cachefactory时却出现了“没有找到构造函数”呢,是我的cachemanager有问题呢,还是我在配置文件中的写法有问题呢?
posted on 2008-09-11 23:58  adow  阅读(2038)  评论(3)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3