作者:鸳鸯520_205 | 来源:互联网 | 2023-09-15 15:16
C#:所以如果静态类是存储全局状态信息的不良做法,那么提供相同方便性的好方法是什么?我一直注意到静态类在用于存储全局信息方面在SO上获得了很多不好的代表。(而且全局变量一般被嘲笑)
C#:所以如果静态类是存储全局状态信息的不良做法,那么提供相同方便性的好方法是什么?
我一直注意到静态类在用于存储全局信息方面在SO上获得了很多不好的代表。 (而且全局变量一般被嘲笑)我只想知道下面的例子有什么好的选择……
我正在开发一个WPF应用程序,并且根据当前登录用户的ID过滤了从我的数据库中检索到的数据的许多视图。 同样,我的应用中的某些点应该只能被视为“管理员”的用户访问。
我目前正在静态类中存储loggedInUserId和isAdmin bool。
我的应用程序的各个部分需要这些信息,我想知道为什么它在这种情况下不理想,以及替代品是什么。 起床和跑步似乎非常方便。
我唯一可以想到的替代方法是使用IoC容器将Singleton实例注入需要此全局信息的类中,然后类可以通过其接口与之通信。 然而,这是否过度/导致我陷入分析瘫痪?
提前感谢您的任何见解。
更新
因此,我倾向于通过IoC进行dependency injection,因为它可以更好地提供可测试性,因为我可以交换一个服务,如果需要,可以使用模拟提供“全局”信息。 我想剩下的是注入的对象是单身还是静态。 ?
如果等待查看是否还有其他讨论,请问问Mark的答案。 我不认为这是正确的方式。 我只是想看到一些可以启发我的讨论,因为似乎有很多“这是坏的”,“这是坏的”,在没有任何建设性替代方案的情况下对某些类似问题的陈述。
更新#2所以我选择了罗伯特的答案,因为它是一个很好的选择(我认为替代方案是一个奇怪的词,可能是One True Way,因为它是内置于框架中)。 它并没有强迫我创建一个静态类/单例(尽管它是线程静态的)。
唯一让我感到好奇的是,如果我必须存储的“全局”数据与用户身份validation无关,那将如何处理。
忘记单身人士和静态数据。 这种访问模式在某个时候会让你失望。
创建自己的自定义IPrincipal并在适当的登录点替换Thread.CurrentPrincipal。 您通常会保留对当前IIdentity的引用。
在用户登录的例程中,例如,您已validation其凭据,请将自定义主体附加到线程。
IIdentity currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity; System.Threading.Thread.CurrentPrincipal = new MyAppUser(1234,false,currentIdentity);
在ASP.Net中,您还可以同时设置HttpContext.Current.User
public class MyAppUser : IPrincipal { private IIdentity _identity; private UserId { get; private set; } private IsAdmin { get; private set; } // perhaps use IsInRole MyAppUser(userId, isAdmin, iIdentity) { if( iIdentity == null ) throw new ArgumentNullException("iIdentity"); UserId = userId; IsAdmin = isAdmin; _identity = iIdentity; } #region IPrincipal Members public System.Security.Principal.IIdentity Identity { get { return _identity; } } // typically this stores a list of roles, // but this conforms with the OP question public bool IsInRole(string role) { if( "Admin".Equals(role) ) return IsAdmin; throw new ArgumentException("Role " + role + " is not supported"); } #endregion }
这是执行此操作的首选方式,并且它在框架中是有原因的。 这样您就可以以标准方式访问用户。
如果用户是匿名的(未知),我们还会执行添加属性的操作,以支持混合匿名/登录身份validation方案的方案。
另外:
这里还有许多其他的答案可以解释为什么静态(包括Singleton)对你不利,所以我不会详细介绍(虽然我全心全意地将这些情绪放在第二位)。
作为一般规则,DI是要走的路。 然后,您可以注入一项服务,告诉您需要了解的有关环境的任何信息。
但是,由于您正在处理用户信息,Thread.CurrentPrincipal可能是一个可行的替代方案(尽管它是 Thread Static)。
为方便起见,您可以围绕它包装强类型的User类 。
我会尝试不同的方法。 静态数据类会让你遇到麻烦 – 这来自经验。 你可以拥有一个User对象(请参阅@Robert Paulson的答案以获得一个很好的方法)并在构建它时将其传递给每个对象 – 它可能对你有用,但你会得到很多模板代码,只能在任何地方重复。
您可以将所有对象存储在具有必要权限的数据库/加密文件中,然后根据您的用户权限动态加载所有这些对象。 使用数据库上的简单管理表单,它很容易维护(文件有点难)。
您可以创建RequiresAdminPermissionAttribute对象以应用于所有敏感对象,并在运行时针对User对象检查它以有条件地加载到对象。
虽然你现在的路线有优点,但我认为还有一些更好的选择。
上述就是C#学习教程:C#:所以如果静态类是存储全局状态信息的不良做法,那么提供相同方便性的好方法是什么?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—编程笔记