So we have a WCF service that provides some object to the client. Our wcf service gets the data from a Data Access Layer (DAL). The DAL gets the data from an API and formats it into an object that we can use. For the most of the objects this works well.
But we also need a list of objects from the API and the objects don't change. The query against the API takes up 15 to 20 seconds. Way to long to run this query multiple times for the same data. So we would like to store the list in memory. Because the DBA's are not our best friends, and SQLite or SQL CE is not an option.
Now we have something like this, the first time the groups are loaded we store them in a private static variable. Is this the right way to do something like this, or is there a better way?
public static class GroupStore
{
private static DTO.Group[] _groups;
public static DTO.Group[] GetAll()
{
if (_groups == null)
{
var dal = PluginHandler.Instance.GetPlugin();
_groups = dal.GetAll();
}
return _groups;
}
}
If you are using .NET4 you can use the Lazy<T> class. It's thread safe and wraps the lazy loading for you.
The code becomes a bit more clean:
public static class GroupStore
{
private static Lazy<DTO.Group[]> _groups = new Lazy<DTO.Group[]>(GetAll);
public static DTO.Group[] Groups { get { return _groups.Value; } }
private static DTO.Group[] GetAll()
{
var dal = PluginHandler.Instance.GetPlugin();
return dal.GetAll();
}
}
Update
The answer that you linked in a comment is OK. But the IsValueCreated uses locking without reason (as the list could have changed between the check and the next access).
I also would not create the value if "ToString" get's called.
A little more clean solution:
public sealed class Lazy<T> where T : class
{
private readonly object _syncRoot = new object();
private readonly Func<T> _factory;
private T _value;
public Lazy(Func<T> factory)
{
if (factory == null) throw new ArgumentNullException("factory");
_factory = factory;
}
public T Value
{
get
{
if (_value == null)
{
lock (_syncRoot)
{
if (_value == null)
{
_value = _factory();
}
}
}
return _value;
}
}
public override string ToString()
{
return _value == null ? "Not created" : _value.ToString();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With