不创建实例的自注册类
本文关键字:注册 创建 实例 | 更新日期: 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中所述的类型的任何方法时才被调用。
类的静态构造函数在给定的应用程序域中最多执行一次。静态构造函数的执行由应用程序域中发生的以下第一个事件触发:
•创建一个类的实例。
•类的任何静态成员都被引用。
请注意,神奇的注册是非常难以编写单元测试的-所以,虽然你的方法可以工作,但可能更好的是使用一些已知的系统,允许注册对象,方便测试。