Reputation: 973
I'm building an intranet using C# webforms. I've got a list object with a bunch of users which I'm cacheing. I'm trying to create a constructor that will do the following when I reference MainADList:
I've got the code to do the caching and retrieving, but it isn't encapsulated nicely in a way that I'd like.
public Users MainADList = new Users();
private void GenerateADList()
{
MainADList = (Users) Cache["MainADList"];
if (MainADList == null || MainADList.Count == 0)
{
//generate the list....
Cache["MainADList"] = MainADList;
}
}
Thanks!
Upvotes: 1
Views: 1237
Reputation: 1500785
You can't create a constructor which does that. A constructor always creates a new object.
Instead, create a static factory method:
public static Users GetUsers()
{
// Consult the cache, and create a new instance if necessary.
}
This may be a singleton - but it certainly doesn't have to be. (I wouldn't artificially impose its singleton-ness unless I really had to. I'm not a big fan of the singleton pattern.)
Alternatively, instead of a static factory method, you could have an instance method in a factory class:
public class UsersFactory
{
// Construct it with a cache, or whatever's required
public Users GetUsers()
{
// Use the cache, or construct a new value.
}
}
Now this is more testable - because you're not relying on any static (global) state. Instead, you can create a new factory from a new cache in each test.
In all of these solutions, you need to consider what threading behaviour you want. If you want to make sure that you only construct the value once, you'll need to use Lazy<T>
, static initializer guarantees, or locking.
Upvotes: 6
Reputation: 14302
One general pattern you could follow:
public class ClassName {
public static Object CachedObject {
get {
Object o = (Object)Cache['CacheKey'];
if (o == null)
{
o = GetData();
Cache["CacheKey"] = o;
}
return o;
}
}
}
And treat ClassName.CachedObject as though it's always, eternally, and magically populated.
Upvotes: 0
Reputation: 3910
What you want is known as a Singleton.
Basically what you should do with the code you already have is something like this:
public static GetList
{
get
{
//check if list exists and create it - so basically call your private constructor
//return cached list
}
}
Upvotes: -3