当我在扩展ICacheManager时遇到的诡异情况

这个问题我搞了一晚上都没有明白,所以贴出来想请大家看看是什么原因。如果管理员觉得不适合放置在首页请移走,很抱歉。

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

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

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

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

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

 48InBlock.gif
 49InBlock.gif        public void Add(string key, object value)
 50ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 51InBlock.gif            IndexusDistributionCache.SharedCache.Add(key, value);
 52InBlock.gif            
 53ExpandedSubBlockEnd.gif        }

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

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

 74ExpandedSubBlockEnd.gif        }

 75InBlock.gif
 76InBlock.gif        public void Flush()
 77ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 78InBlock.gif            IndexusDistributionCache.SharedCache.Clear();
 79ExpandedSubBlockEnd.gif        }

 80InBlock.gif
 81InBlock.gif        public object GetData(string key)
 82ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 83InBlock.gif            return IndexusDistributionCache.SharedCache.Get(key);
 84ExpandedSubBlockEnd.gif        }

 85InBlock.gif
 86InBlock.gif        public void Remove(string key)
 87ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 88InBlock.gif            IndexusDistributionCache.SharedCache.Remove(key);
 89ExpandedSubBlockEnd.gif        }

 90InBlock.gif
 91InBlock.gif        public object this[string key]
 92ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 93InBlock.gif            get
 94ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 95InBlock.gif                return this.GetData(key);
 96ExpandedSubBlockEnd.gif            }

 97ExpandedSubBlockEnd.gif        }

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

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

115InBlock.gif            return IndexusMessage.CacheItemPriority.Normal;
116ExpandedSubBlockEnd.gif        }

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

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

133ExpandedSubBlockEnd.gif            }

134InBlock.gif            return DateTime.MinValue;
135ExpandedSubBlockEnd.gif        }

136InBlock.gif
137InBlock.gif        public void Dispose()
138ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
139InBlock.gif            GC.SuppressFinalize(this);
140ExpandedSubBlockEnd.gif        }

141ExpandedSubBlockEnd.gif    }

142ExpandedBlockEnd.gif}



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

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

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

ContractedBlock.gif ExpandedBlockStart.gif 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的方式来构造也没有问题:

ContractedBlock.gif ExpandedBlockStart.gif Code
1None.gifIUnityContainer container = new UnityContainer();
2None.gifcontainer.RegisterType<ICacheManager,ShireCacheManagerIndexus>("indexus");
3None.gifmanager = container.Resolve<ICacheManager>("indexus");

问题是后两种都忽略了配置文件的存在,手工来创建cachemanager,没有实际意义。
然而,为什么我在使用cachefactory时却出现了“没有找到构造函数”呢,是我的cachemanager有问题呢,还是我在配置文件中的写法有问题呢?

转载于:https://www.cnblogs.com/adow/archive/2008/09/11/entlib-icachemanager.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值