user948060
user948060

Reputation: 973

Create constructor(?) to retrieve object from cache or recreate if null

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:

  1. if it exists in the cache and is not null, use it
  2. else generate the list and cache it

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

Answers (3)

Jon Skeet
Jon Skeet

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

svidgen
svidgen

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

dutzu
dutzu

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

Related Questions