【发布时间】:2013-07-12 17:59:59
【问题描述】:
作为尝试对另一个问题提出答案的一部分,我想创建一个Dictionary 的自注册单例实例。具体来说,是这样的:
public abstract class Role
{
public static Dictionary<string, Role> Roles = new Dictionary<string, Role>();
protected Role()
{
_roles.Add(this.Name, this);
}
public abstract string Name { get; }
}
public class AdminRole : Role
{
public static readonly AdminRole Instance = new AdminRole();
public override string Name { get { return "Admin"; } }
}
但是,除非我访问 Instance,否则不会调用 AdminRole 构造函数,因此它不会被添加到 Roles 字典中。我知道我可以使用{ AdminRole.Instance.Name, Admin Role} 来实例化字典,但我想添加新角色以不需要更改Role 类。
有什么建议吗?这甚至是通过字符串访问单例的好设计吗?
测试结果的代码行是:
var role = Role.Roles["Admin"];
如果没有得到KeyNotFound 异常(或null),则表示成功。
可以显式初始化 Role(例如 Role.Initialize()),但不是子类 - 想法是能够添加子类,以便字典拥有它,无需更改任何已存在的内容。
【问题讨论】:
-
您不想在
Role中更改Dictionary的原因 - 您不想对每个新的子类型进行更改,或者您永远不想进行更改? -
@nsinreal - 前者。我希望能够创建一个新的
Role类型,而无需做任何其他事情,只需对其进行子类化。 -
好的,明白了。反射
-
@nsinreal - 最初的提问者不想“扫描整个程序集以查找
IRoles”。我很擅长反射,只要它在Role中完全独立。 -
还有另一种方法。您可以从
Role类中提取Name,并按照约定命名使其工作。你用你的方法GetInstance(key)或者你的代理类替换你的字典。调用 GetInstance 后,您首先检查您的字典。如果没有这样的角色,则使用 GetType(key + "Role") 遍历加载到程序的所有程序集并使用它。
标签: c# design-patterns initialization singleton static-constructor