在我的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;
}
}
提前致谢
答案 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实例时,您还会创建一个新的字典实例。