使用工厂类中的词典进行缓存

时间:2015-04-15 08:55:31

标签: c# wpf dictionary

在我的WPF应用程序中,我正在使用第三方库来获取我想让用户与之交互的对象。

对象作为接口类型返回,我已经为它们创建了包装类。我还创建了一个Factory类来实例化包装类。 在工厂类中,我使用字典为每个不同的包装器类型缓存包装器对象。

使用字典来缓存这些包装器对象是一个很好的方法吗?这里有明显的问题吗?

public interface ICustomer // 3rd party Interface
{
    string Name {get; }
    string Address {get }

    // etc
}

public class ClientCustomer : IClientCustomer // Wrapper class
{
     ICustomer customer;
     public ClientCustomer(ICustomer cust)
     {
       this.customer = cust;
     }

     public string Name
     {
        get
        {
           return customer.Name;
        }
     }

    // etc
}

public class VmFactory
{
   private Dictionary<int, IClientCustomer> clientCustomers = 
        new Dictionary<int, IClientCustomer>();

    public IClientCustomer GetCustomerWrapper(ICustomer cust)
    {
       IClientCustomer clientCustomer;

       if (!clientCustomers.ContainsKey(cust.ID))
        {
            clientCustomer = new ClientCustomer(cust);
            clientCustomers.Add(cust.ID, clientCustomer);
        }
        else
        {
            clientCustomer = clientCustomers[cust.ID];
        }

          return clientCustomer;
   }

}

提前致谢

2 个答案:

答案 0 :(得分:2)

首先,是的,您可以使用字典进行缓存,但需要考虑线程安全,缓存过期,失效等。我将进一步提出替代解决方案。

就像@Coastpear已经指出的那样,你使用它的方式并不好,因为你的Dictionary被声明为一个实例变量。它需要有一个静态实例才能缓存多个工厂实例。如果您的应用程序是多线程的,那么您还需要同步对它的访问才能保证线程安全。注意:如果您在应用的生命周期中只有一个工厂实例,则字典不必是静态的,但如果您从多个访问它,您仍需要同步对它的访问权限线程。

因此,我建议使用ConcurrentDictionary,而不是使用词典。访问字典本质上是线程安全的(你只需要担心它的内容)

public class VmFactory
{
   private static ConcurrentDictionary<int, IClientCustomer> clientCustomers = 
        new ConcurrentDictionary<int, IClientCustomer>();

    public IClientCustomer GetCustomerWrapper(ICustomer cust)
    {
       IClientCustomer clientCustomer;

       if (!clientCustomers.ContainsKey(cust.ID))
        {
            clientCustomer = new ClientCustomer(cust);
            clientCustomers.TryAdd(cust.ID, clientCustomer);
        }
        else
        {
            clientCustomer = clientCustomers[cust.ID];
        }

          return clientCustomer;
   }
}

另请参阅MemoryCache作为另一种选择,尽管我认为ConcurrentDictionary足以满足您的需求。

答案 1 :(得分:0)

如果在VmFactory中验证(对于多线程环境),您应该使用带有double的Singleton,以确保您只有一个字典实例,因为每次创建VmFactory实例时,您还会创建一个新的字典实例。