Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a static constructor has been called?

I have some classes that caches data from a database, these classes are loaded with data when their static constructor gets called.

I need to call a static Reload method at all these classes, except those that is not initialized yet.

E.g.: City caches data from a database

public class City
{
    public City Get(string key)
    {
        City city;
        FCities.TryGetValue(key, out city);
        return city;
    }
    private static Dictionary<string, City> FCities;

    static City()
    {
        LoadAllCitiesFromDatabase();
    }

    public static void Reload()
    {
        LoadAllCitiesFromDatabase();
    }

    private static void LoadAllCitiesFromDatabase()
    {
        // Reading all citynames from database (a very slow operation)
        Dictionary<string, City> loadedCities = new Dictionary<string, City>();
        ...
        FCities = loadedCities;
    }
}

The problem is that City might not have been used yet (it might not be used in this service) and there is no reason to load it from the database then.

My reload all method looks much like this:

public static class ReloadAll
{
    public static void Do()
    {
        foreach (Type classType in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => t.IsClass && !t.IsAbstract))
        {
            MethodInfo staticReload = classType.GetMethods().FirstOrDefault(m => m.IsStatic && m.IsPublic && m.ReturnType == typeof(void) && m.Name == "Reload" && m.GetParameters().Length == 0);
            if (staticReload != null)
            {
                if (StaticConstructorHasBeenCalled(classType))
                    staticReload.Invoke(null, null);
            }
        }
    }

    private bool StaticConstructorHasBeenCalled(Type classType)
    {
        // How do I check if static constructor has been called?
        return true;   
    }
}

I need a little help with implementing StaticConstructorHasBeenCalled.

like image 648
Casperah Avatar asked Jan 28 '13 15:01

Casperah


Video Answer


1 Answers

At first glance, I thought this could be an issue where <grin> Quantum Mechanical Copenhagen interpretation might apply ("As soon as you look at it, it changes"). </grin> I.e. anything you do in the class to observe whether it has been initialized would probably cause it to initialize itself...

But you don't have to do it in the class, just keep a list somewhere else (other than in any of these static classes) that is populated by every static class when it gets initialized. Then in your reset function, just iterate through the classes in the list.

like image 135
Charles Bretana Avatar answered Oct 21 '22 14:10

Charles Bretana