C#:所以,如果一个静态类是不好的做法,用于存储全局状态信息,那是什么提供了同样的方便一个很好的选择? [英] C# : So if a static class is bad practice for storing global state info, what's a good alternative that offers the same convenience?

查看:135
本文介绍了C#:所以,如果一个静态类是不好的做法,用于存储全局状态信息,那是什么提供了同样的方便一个很好的选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经注意到静态类得到了很多坏名声对SO的问候用于存储全局信息。 (和全局变量被一般在嘲笑)我只是想知道一个很好的选择是什么?以下

I've been noticing static classes getting a lot of bad rep on SO in regards to being used to store global information. (And global variables being scorned upon in general) I'd just like to know what a good alternative is for my example below...

我正在开发一个WPF我的榜样应用程序,并从我的数据库中检索到的数据的多个视图被过滤根据登录的用户的当前的ID。同样,在我的应用程序的某些点应该只accessable到谁被视为管理员的用户。

I'm developing a WPF app, and many views of the data retrieved from my db are filtered based on the ID of the current logged in user. Similarly, certain points in my app should only be accessable to users who are deemed as 'admins'.

我目前存储的 loggedInUserId isAdmin 布尔在一个静态类。

I'm currently storing a loggedInUserId and an isAdmin bool in a static class.

我的应用程序的不同部分需要这个信息,我不知道为什么它不是在这个理想情况下,以及替代方案是什么。它似乎很convienient起床和运行。

Various parts of my app need this info and I'm wondering why it's not ideal in this case, and what the alternatives are. It seems very convienient to get up and running.

我能想到作为一个替代方案是使用IoC容器注入一个Singleton实例成需要的类的唯一的事情全球性的信息,这些类可以再通过其界面跟这一点。然而,这是矫枉过正/带领我进入分析瘫痪?

The only thing I can think of as an alternative is to use an IoC Container to inject a Singleton instance into classes which need this global information, the classes could then talk to this through its interface. However, is this overkill / leading me into analysis paralysis?

在提前为任何见解感谢。

Thanks in advance for any insight.

< HR />

更新

所以,我对通过依赖注入靠在国际奥委会它会更好地适合以可测性,因为我可以在必要时,提供了模拟的全球信息服务交换。我想,剩下的就是被注入的对象是否不应该是一个单身或静态的。 : - )

So I'm leaning towards dependency injection via IoC as It would lend itself better to testability, as I could swap in a service that provides "global" info with a mock if needed. I suppose what remains is whether or not the injected object should be a singleton or static. :-)

概率会挑马克的回答虽然等待看看是否有任何更多的讨论。我不认为有这样一个正确的方式。我只是有兴趣看到一些讨论,这将开导我,似乎有很多这是不好的,这是在没有任何建设性的替代方案有些类似的问题坏的语句。

Will prob pick Mark's answer although waiting to see if there's any more discussion. I don't think there's a right way as such. I'm just interested to see some discussion which would enlighten me as there seems to be a lot of "this is bad" "that is bad" statements on some similar questions without any constructive alternatives.


更新#2
于是我拿起罗伯特的回答看,因为它是一个伟大的另类(我猜的替代是一个奇怪的词,可能是唯一正确的方法看到它内置框架)。这不是逼着我建立一个静态类/单身(虽然它是线程静态)。

Update #2 So I picked Robert's answer seeing as it is a great alternative (I suppose alternative is a weird word, probably the One True Way seeing as it is built into the framework). It's not forcing me to create a static class/singleton (although it is thread static).

这还是让我好奇的唯一事情是如何做到这一点已经被解决,如果全局的数据,我不得不店不得不无关,与用户身份验证。

The only thing that still makes me curious is how this would have been tackled if the "global" data I had to store had nothing to do with User Authentication.

推荐答案

忘记单身和静态数据。访问该模式会在一段时间内让您失望。

Forget Singletons and static data. That pattern of access is going to fail you at some time.

创建自己的自定义的IPrincipal,并在一个点登录是适当用它取代Thread.CurrentPrincipal中。通常,您可以保持参照当前的IIdentity。

Create your own custom IPrincipal and replace Thread.CurrentPrincipal with it at a point where login is appropriate. You typically keep the reference to the current IIdentity.

在你的日常当用户登录时,例如你已经验证他们的凭据,附上您的自定义主要的主题。

In your routine where the user logs on, e.g. you have verified their credentials, attach your custom principal to the Thread.

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
}

这是首选的方法要做到这一点,它是在是有原因的框架。这样,您就可以在一个标准的方式获取用户。

This is the preferred way to do it, and it's in the framework for a reason. This way you can get at the user in a standard way.

我们还做这样的事情,如果用户是匿名的(未知),支持混合匿名的情况下添加属性。/登录的身份验证方案

We also do things like add properties if the user is anonymous (unknown) to support a scenario of mixed anonymous/logged-in authentication scenarios.

此外:


  • 您仍然可以使用DI(依赖关系注入)注入检索/支票凭证的会员服务。

  • 您可以使用Repository模式也获得当前MyAppUser(尽管它无疑只是让演员来MyAppUser的你,可以有利益这一点)

这篇关于C#:所以,如果一个静态类是不好的做法,用于存储全局状态信息,那是什么提供了同样的方便一个很好的选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆