对Lazy <t>单例代码

时间:2016-10-06 08:09:27

标签: c# .net generics singleton func

根据Jon Skeet的书核here中提供的第6版创建单例类。

类 - CacheSingleton

public sealed class CacheSingleton<TK,TV>
    {
        private static readonly Lazy<ICache<TK,TV>> lazyIgnite =
                                                new Lazy<ICache<TK,TV>>(() =>
                                                {
                                                    NearCacheConfiguration nearCacheConfig = new NearCacheConfiguration { NearStartSize = 10240000 };

                                                    var nearCache = IgniteInstance.GetOrCreateNearCache<TK, TV>(SingletonCacheName,nearCacheConfig);

                                                    return nearCache;
                                                });

        /// <summary>
        /// 
        /// </summary>
        private static string SingletonCacheName = string.Empty;

        /// <summary>
        /// 
        /// </summary>
        public static ICache<TK, TV> Instance(string cacheName)
        {
            SingletonCacheName = cacheName;
            return lazyIgnite.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        private CacheSingleton() { }
    }

对原始文章的修改:

  • Instance是一个方法而不是属性,因为我需要提供CacheName,用于获取正确的缓存

的问题:

  • 即使使用当前修改,我也只能为Tk,TV类型的组合获取特定的Cache实例,因为除了第一次,第二次,我无法将string输入因素考虑在内即使字符串值不同,它总是会获取相同的实例。
  • 问题的主要原因是Lazy类型需要Func<T>,而且没有附加参数的范围。

指向字符串输入中的因子的任何指针,以及TK,TV

2 个答案:

答案 0 :(得分:3)

如何使用ConcurrentDictionary

public static class CacheSingleton<TK, TV>
{
    private static readonly ConcurrentDictionary<string, ICache<TK, TV>> lazyIgnite = new ConcurrentDictionary<string, ICache<TK, TV>>();

    public static ICache<TK, TV> GetInstance(string cacheName)
    {
        return lazyIgnite.GetOrAdd(cacheName, name =>
        {
            NearCacheConfiguration nearCacheConfig = new NearCacheConfiguration { NearStartSize = 10240000 };
            var nearCache = IgniteInstance.GetOrCreateNearCache<TK, TV>(name, nearCacheConfig);
            return nearCache;
        });
    }
}

这是您的实例的延迟和线程安全缓存。 也许您还想实现Clear方法来重置缓存。

答案 1 :(得分:2)

你不能使用ConcurrentDictionary来实现这个吗?类似的东西:

public static class CacheSingleton<TK, TV>
{
    public static ICache<TK, TV> Instance(string cacheName)
    {
        return _cache.GetOrAdd(cacheName, create);
    }

    static ICache<TK, TV> create(string cacheName)
    {
        // Code to create an ICache<TK, TV> given cacheName.

        return null; // Stubbed.
    }

    static readonly ConcurrentDictionary<string, ICache<TK, TV>> _cache = new ConcurrentDictionary<string, ICache<TK, TV>>();
}