Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不创建实例的自注册类_C# - Fatal编程技术网

C# 不创建实例的自注册类

C# 不创建实例的自注册类,c#,C#,在我的应用程序中,有一组数据提供程序和Redis缓存。 每个执行都使用不同的提供程序,但它们都在Redis中存储自己的数据: hset ProviderOne Data "..." hset ProviderTwo Data "..." 我想有一个方法,将删除代码中存在的所有提供者的数据 del ProviderOne del ProviderTwo 我制定了下一个代码: void Main() { // Both providers have static fie

在我的应用程序中,有一组数据提供程序和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
    {

    }
void Main()
{
//两个提供程序都具有默认值的静态字段哈希。
//我希望静态字段应该在应用程序启动时初始化,
//然后初始化将调用CacheRepository.Register()方法
//所有类都将在CacheRepository.RegisteredHashes中自行注册它们。
//但代码只有在我创建此类时才开始工作(至少一次)
//新ProviderOne();
//新提供者2();
CacheRepository.Reset();
}
公共抽象类抽象提供者
{
//...
}
公共类ProviderOne:AbstractProvider
{
公共静态只读字符串哈希=
CacheRepository.Register();
//...
}
公共类提供者二:抽象提供者
{
公共静态只读字符串哈希=
CacheRepository.Register();
//...
}
公共类缓存存储库
{
受保护的静态LazyInstance=new Lazy();
公共静态缓存存储库实例
{
获取{return LazyInstance.Value;}
}
public ConcurrentBag RegisteredHashes=新ConcurrentBag();
公共静态字符串寄存器()
{
字符串哈希=typeof(T).Name;
如果(!Instance.RegisteredHashes.Contains(哈希))
{
RegisteredHashes.Add(散列);
}
返回散列;
}
公共静态无效重置()
{
foreach(Instance.registeredHash中的字符串registeredHash)
{
Reset(registeredHash);
}
}
受保护的无效重置(字符串哈希);
}
接口IData{}
接口IDataProvider
{
字符串GetRedisHash();
IDataGetData();
}
不可抗力
{
}

如何使其工作?

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

   public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Provider1.Name + Provider2.Name);
            Console.ReadLine();
        }
    }
在C#中,静态构造函数(初始化所有静态字段的构造函数)仅在使用C#规范中包含的任何类型的方法时才被调用:

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


请注意,神奇的注册很难编写单元测试-因此,尽管您的方法可行,但最好使用一些已知的系统,允许注册方便测试的对象。

您不一定需要创建实例。一旦调用任何静态方法或属性,它们就会被初始化。您需要在使用它们之前自动初始化它们有什么原因吗?您可能想检查一下这个问题。也许一个接口和一些反射可以很好地配合第二个答案:类是否必须注册自己,或者您只是希望在加载dll时注册类?为什么不使用MEF?您是指MEF?我试图避免在一个地方创建包含所有提供程序的集合。其思想是使它们能够自给自足,而无需在代码的其他部分直接声明它们。从另一方面来说,我希望有一个简单的删除过程,而不会有人忘记排除删除的提供者