2013-06-01 23 views
0

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

    } 

如何使它的工作?

+1

您不一定需要创建实例。一旦任何静态方法或属性被调用,它们将被初始化。是否有什么原因需要它们在你使用它们之前自动初始化? – TyCobb

+0

你可能想检查这个问题。也许一个接口和一些反射会很好地与第二个答案:http://stackoverflow.com/questions/8748492/how-to-initialize-ac-sharp-static-class-before-it-is-actually-needed – TyCobb

+0

这个类是否需要自己注册,或者你是否只想在加载dll时注册类? – FriendlyGuy

回答

1

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

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

在C#静态构造函数(即初始化所有静态字段)只称为如果类型的任何方法被用作覆盖在C#规范中10.11 Static constructors

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

请注意,神奇的注册非常难以编写单元测试 - 因此,尽管您的方法可行,但使用某些已知系统可以更好地注册对象以方便测试。

+0

我试图避免在一个地方创建一个与所有提供者的集合。这个想法是让他们自给自足,而不是在代码其他部分的其他地方直接声明他们。从另一方面来说,我希望有一个简单的删除过程,而不会有人可以忘记排除已删除的提供者 –