C# 不创建实例的自注册类
在我的应用程序中,有一组数据提供程序和Redis缓存。 每个执行都使用不同的提供程序,但它们都在Redis中存储自己的数据:C# 不创建实例的自注册类,c#,C#,在我的应用程序中,有一组数据提供程序和Redis缓存。 每个执行都使用不同的提供程序,但它们都在Redis中存储自己的数据: hset ProviderOne Data "..." hset ProviderTwo Data "..." 我想有一个方法,将删除代码中存在的所有提供者的数据 del ProviderOne del ProviderTwo 我制定了下一个代码: void Main() { // Both providers have static fie
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?我试图避免在一个地方创建包含所有提供程序的集合。其思想是使它们能够自给自足,而无需在代码的其他部分直接声明它们。从另一方面来说,我希望有一个简单的删除过程,而不会有人忘记排除删除的提供者