不创建实例的自注册类

本文关键字:注册 创建 实例 | 更新日期: 2023-09-27 18:16:25

在我的应用程序有一组数据提供程序和Redis缓存。每次执行都使用不同的提供商,但它们都在Redis中存储自己的数据:

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

我想有一个方法,将删除所有提供程序的数据存在于代码。

del ProviderOne
del ProviderTwo

我已经做了下一个代码:

   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
    {
    }

如何使它工作?

不创建实例的自注册类

您可以访问类的任何静态方法/属性-即Provider1.Name:

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

在c#中,静态构造函数(初始化所有静态字段的构造函数)只有在使用c#规范10.11中所述的类型的任何方法时才被调用。

类的静态构造函数在给定的应用程序域中最多执行一次。静态构造函数的执行由应用程序域中发生的以下第一个事件触发:
•创建一个类的实例。
•类的任何静态成员都被引用。

请注意,神奇的注册是非常难以编写单元测试的-所以,虽然你的方法可以工作,但可能更好的是使用一些已知的系统,允许注册对象,方便测试。