0

In my Application a have a set of Data Providers and Redis Cache. Each execution different providers are used, but they all store own Data in Redis:

hset ProviderOne Data "..."
hset ProviderTwo Data "..."

I would like have one method That will delete Data for all providers that are present in code.

del ProviderOne
del ProviderTwo

I have made next code:

   void Main()
   {
       // Both providers have static field Hash with default value.
       // I expected that static fields should be initialized when application starts,
       // then initialization will call CacheRepository.Register<T>() method
       // and all classes will register them self in CacheRepository.RegisteredHashes.

       // But code start working only when i created this classes (at least once)
       // new ProviderOne();
       // new ProviderTwo();

       CacheRepository.Reset();
   }

   public abstract class AbstractProvider
   {
      //...
   }

   public class ProviderOne : AbstractProvider
   {
       public static readonly string Hash = 
          CacheRepository.Register<ProviderOne>();

       //...
   }

   public class ProviderTwo : AbstractProvider
   {
       public static readonly string Hash = 
          CacheRepository.Register<ProviderTwo>();

       //...
   }

   public class CacheRepository
    {
        protected static Lazy<CacheRepository> LazyInstance = new Lazy<CacheRepository>();

        public static CacheRepository Instance
        {
            get { return LazyInstance.Value; }
        }

        public ConcurrentBag<string> RegisteredHashes = new ConcurrentBag<string>();

        public static string Register<T>()
        {
            string hash = typeof(T).Name;

            if (!Instance.RegisteredHashes.Contains(hash))
            {
                Instance.RegisteredHashes.Add(hash);
            }

            return hash;
        }

        public static void Reset()
        {
            foreach (string registeredHash in Instance.RegisteredHashes)
            {
                Instance.Reset(registeredHash);
            }
        }

        protected void Reset(string hash);
    }



    interface IData{}

    interface IDataProvider
    {
       string GetRedisHash();
       IData GetData();
    }

    intefrace IRedisRepository
    {

    }

How make it working?

Vlad Mysla
  • 1,181
  • 12
  • 15
  • 1
    You don't necessarily need to create an instance. They will get initialized as soon as any static method or property is called. Is there a reason you need them to auto initialize before you have even used them? – TyCobb Jun 01 '13 at 02:34
  • You may want to check this question out. Perhaps an interface and some reflection would work nicely with the 2nd answer: http://stackoverflow.com/questions/8748492/how-to-initialize-a-c-sharp-static-class-before-it-is-actually-needed – TyCobb Jun 01 '13 at 02:48
  • Does the class have to register itself, or do you just want the class registered whenever the dll is loaded? – zastrowm Jun 01 '13 at 03:40
  • why not to work with MEF – li-raz Jun 01 '13 at 03:42
  • what you mean with MEF? – Vlad Mysla Jun 01 '13 at 17:41

1 Answers1

1

You can just access any static method/property of your class - i.e. Provider1.Name:

   public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Provider1.Name + Provider2.Name);
            Console.ReadLine();
        }
    }

In C# static constructor (one that initializes all static fields) is called only if any method of type is used as covered in C# specification 10.11 Static constructors:

The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
•An instance of the class is created.
•Any of the static members of the class are referenced.

Note that magical registration is very hard to write unit tests for - so while your approach would work it may be better to use some known system that allow registering objects that is convenient to test.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • i tried to avoid creation of a collection with all providers in one place. the idea is to make them self-sufficient, without direct declarations for them somewhere else in other parts of the code. from other side, i would like to have easy removal process without a chance that somebody can forget to exclude deleted provider – Vlad Mysla Jun 01 '13 at 17:39