开发者

How to initialise a class at program startup?

开发者 https://www.devze.com 2023-01-19 13:08 出处:网络
class Statistics { Dictionary<decimal, Statistic> BabyDataStandardAgeHeadCircumference; Dictionary<decimal, Statistic> BabyDataStandardAgeLength;
 class Statistics
{
    Dictionary<decimal, Statistic> BabyDataStandardAgeHeadCircumference;
    Dictionary<decimal, Statistic> BabyDataStandardAgeLength;
    Dictionary<decimal, Statistic> BabyDataStandardAgeWeight;
    Dictionary<decimal, Statistic> BabyDataStandardWeightForLength;


}

These data are fixed - readonly and i want to load them from t开发者_如何学Pythonhe database. The problem is

  1. How to make them readonly ?(i know through properties)
  2. How to fill them with data at program startup ?

Calling a method like Statistics.load() from startup event seems poor to me..


If you make them readonly or use properties, the dictionaries themselves will still be modifiable. One option is to make them private and provide GetXXX methods to retrieve the values.

class Statistics
{
    private static Dictionary<decimal, Statistic> babyDataStandardAgeHeadCircumference;
    private static Dictionary<decimal, Statistic> babyDataStandardAgeLength;
    private static Dictionary<decimal, Statistic> babyDataStandardAgeWeight;
    private static Dictionary<decimal, Statistic> babyDataStandardWeightForLength;

    static Statistics() 
    {
        // Put code to load from database here.  Will get called *once* when 
        // the *class* is first initialized.
    }

    public Statistic GetBabyDataStandardAgeHeadCircumfrence(decimal val) 
    {
        return babyDataStandardAgeHeadCircumfrence[val];
    }

    ...
}


Question:

How to make them readonly ?(i know through properties)

Answer: Rather than using a Dictionary<decimal, Statistics>, think about using an immutable wrapper for the dictionary.

SO link for an implementation of an immutable Dictionary class here:

Does C# have a way of giving me an immutable Dictionary?

Question:

How to fill them with data at program startup ?

Answer: Rather than fill them with data at program startup, how about filling them at the first access to the class (static or instanced)? This would mean populating these dictionaries in the static constructor (naturally the dictionaries would have to be static members as well).

public class Statistics
{
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardAgeHeadCircumference;
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardAgeLength;
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardAgeWeight;
    public static readonly ImmutableDictionary<decimal, Statistic> 
        BabyDataStandardWeightForLength;

    static Statistics()
    {
        // populate the dictionaries here...
    }
}


Making it read-only: make yourself a wrapper class implementing IDictionary in a read-only manner.

Initializing upon application start-up:

  • If you do need precise order of initialization operations, the Statistics.Load() approach isn't anything odd. Also, this gives you a reasonable room for error handling in case of database connection failures.
  • If you don't have to care of order of initialization, use a static constructor. By following this approach you'll have to make sure the database is accessible (in other words, there won't be any legitimate error situations) and that the first use of the class (which actually triggers the static constructor) isn't “too soon”.


Make a class that can create, load, and return your Statistics class, I would expose the method that does so through an interface:

public interface IStatisticsRepository {
    Statistics GetStatistics();
}

public class StatisticsRepository : IStatisticsRepository {

    private Statistics _statistics = null;

    private void LoadStatistics() {
         _statistics = GetFromDBHere();
    }

    public Statistics GetStatistics() {
        if (_statistics == null) {
            LoadStatistics();
        }

        return _statistics;

}

Then, your implementation of that interface is a service that can be used wherever. I'd inject it anywhere you need to get your statistics.


Actually, the properties you listed are collections based on the Dictionary class. The management (Add(), Remove(), [] indexer) of objects in a Dictionary is accessible by any instance that can see the BabyData... objects. In other words, you cannot make them read-only because the Dictionary class does not support that mode of operation via properties. You would have to declare the Dictionary as private and then interface each one via methods. This is the "dirty" approach.

OR, you can create a class based on the Dictionary class that controls the addition of objects via overloading. This is more complicated, but more in tune with what you are needing (from what I can understand).

As far as loading from the database, you'd need to tell us how you are able to fetch data from the database (via Sql, Linq to Sql, DataSet table adapters, etc.) to determine what is the best method for fetching the data into your Dictionary collections.


You could make the Statistics class follow the Singleton Pattern; and in the Instance property get create an instance if one is not already created:

class Statistics
{
    private static Statistics sInstance;
    private static Object sInstanceLock = new Object();
    private Statistics() {
        // Load data from database here...
    }
    public static Statistics Instance {
        get {
            lock(sInstanceLock) {
                if(sInstance == null) {
                    sInstance = new Statistics();
                }
                return sInstance;
            }
        }
    }
}

This would mean initialization would not necessarily have to take place at startup, although you could by invoking the Instance property at startup.

As for the read-only aspects I am not sure what your requirements are. If you mean that no one would be able to change the dictionary (add an element, remove an element) you could look at the answer to the question here: Immutable Dictionary. If you mean that no one can change the object that is stored as the value at a particular entry in the dictionary, then you would have to make the class or value type that is stored there immutable, the String class in .Net is an example of this.

0

精彩评论

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