Create constructor(?) to retrieve object from cach

2019-07-31 16:05发布

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!

3条回答
我只想做你的唯一
2楼-- · 2019-07-31 16:44

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.

查看更多
Lonely孤独者°
3楼-- · 2019-07-31 16:51

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.

查看更多
Anthone
4楼-- · 2019-07-31 17:05

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
      }
}
查看更多
登录 后发表回答