开发者

C# Where to load initial data in an object?

Similar to this question: C# Constructor Design but this question is slight different.

I have a class Customer and a class CustomerManager. When an instance is created of the CustomerManager class I want to load all the customers. And this is where I got stuck. I can do this several ways:

  1. Load all the customers in the constructor (I don't like this one because it can开发者_Go百科 take a while if I have many customers)
  2. In every method of the CustomerManager class that performs database related actions, check the local list of customers is loaded and if not, load the list:

    public method FindCustomer(int id)
    {
      if(_customers == null)
      // some code which will load the customers list
    }
    
  3. Create a method which loads all the customers. This method must be called before calling methods which performs database related actions:

    In the class:

    public LoadData()
    {
       // some code which will load the customers list
    }
    

    In the form:

    CustomerManager manager = new CustomerManager();
    manager.LoadData(); 
    Customer customer = manager.FindCustomer(int id);
    

What is the best way to do this?

EDIT:

I have the feeling that I am misunderstood here. Maybe it is because I wasn't clear enough. In the CustomerManager class I have several methods which depends on the local list (_customers). So, my question is, where should I fill that list?


What you are describing is "lazy loading".

A simple approach is to have a private property like this:

private Lixt<Customer> _customers;
private List<Customer> Customers
{
  get
  {
    if(_customers == null)
      _customers = LoadData();
    return _customers;
  }
}

Then, you refer to Customers internally. The customers will be loaded the first time they are needed but no earlier.

This is such a common pattern that .Net 4.0 added a Lazy<T> class that does this for you.

I that case, you just define it as a private like this:

private Lazy<List<Customer>> _customers = new Lazy<List<Customer>>(LoadData);

Then, you simply refer to your customers in code:

_customers.Value

The class will initialize the value with your LoadData() method.

If you are not on .Net 4.0 yet, the Lazy<T> class is very easy to implement.


Use a property for accessing the customers. Have that check if the customers are loaded.


Well, it depends. All your options have advantages and disadvantages.

The good thing about options 1 and 3 is that the user has full control over when the (lengthy) data loading operation is performed. Whether option 1 or 3 is better depends on whether it makes sense to create the Manager and load the data later or not. Personally, I prefer a separate LoadData method if it's a lengthy operation, but that might be a matter of taste.

The good thing about option 2 is that the data will not be loaded if it is not needed. The drawback is that the (lengthy) load occurs as a side-affect of the first access, which makes your program "less deterministic".

In principle, all the options you have presented are fine and valid choices. It really depends on your requirements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜