【问题标题】:Winforms: access class properties throughout applicationWinforms:在整个应用程序中访问类属性
【发布时间】:2009-08-11 07:10:33
【问题描述】:

我知道这一定是一个古老而疲惫的问题,但我似乎无法通过我可信赖的朋友(又名 Google)找到任何东西。

我有一个 .net 3.5 c# winforms 应用程序,它在应用程序启动时向用户显示登录表单。成功登录后,我想跑到数据库,拉入一些特定于用户的数据并将它们(在属性中)保存在一个名为 AppCurrentUser.cs 的类中,这样就可以在所有用户中访问程序集中的类 - 这里的目的是我可以使用一次性读取的数据填充一些属性,而不是每次需要时都调用数据库。在 web 应用程序中,我通常会使用 Session 变量,我知道 WinForms 中不存在这种概念。

类结构如下所示:

public class AppCurrentUser {

    public AppCurrentUser() { }

    public Guid UserName { get; set; }
    public List<string> Roles { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
} 

现在,我有一些选项需要专家建议:

作为一个“哑”类,我应该使属性成为非静态的,实例化该类,然后设置属性...但是我将只能从创建它的类中访问该实例对吧?

从逻辑上讲,我认为这些属性应该是静态的,因为我只会在整个应用程序中使用类一次(并且不会创建它的新实例),并且它的属性值将在应用程序关闭时“重置”。 (如果我创建它的一个实例,我可以在应用程序关闭时处理它)

我应该如何构建我的类以及如何在我的程序集中的所有类中访问它的属性?我真的很感谢您对此的诚实和有价值的建议!

谢谢!

【问题讨论】:

    标签: winforms singleton global-variables


    【解决方案1】:

    在这里使用单例模式:

    public class AppUser
    {
        private static _current = null;
        public static AppUser Current
        {
            get { return = _current; }
        }
    
        public static void Init()
        {
            if (_current == null)
            {
                _current = new AppUser();
                // Load everything from the DB.
                // Name = Dd.GetName();
            }
        }
    
        public string Name { get; private set; }
    }
    
    // App startup.
    AppUser.Init();
    
    // Now any form / class / whatever can simply do:
    var name = AppUser.Current.Name;
    

    现在“静态”的东西是线程不安全的。我将把它留给读者练习,以了解如何正确使用 lock() 语法以使其成为线程安全的。如果在调用 Init 之前访问 Current 属性,您还应该处理这种情况。

    【讨论】:

      【解决方案2】:

      这取决于您如何设置架构。如果您在实际表单中执行所有业务逻辑代码(例如,将其耦合到 UI),那么您可能希望在制作表单时将用户信息作为参数传递,然后在其中保留对它的引用形式。换句话说,您将实现Singleton 模式。

      您也可以使用依赖注入,这样每次您请求用户对象时,依赖注入框架(如StructureMap)都会为您提供正确的对象。 -- 您可能可以将它用作会话变量,因为您将在有状态的环境中工作。

      【讨论】:

      • 嗨!谢谢回复!不,我的 BL 在一个单独的类中并从 UI 调用。另外,我的静态与非静态参数是否有效?
      • 我想说 DI 在这里是矫枉过正。 Shalan 听起来他可能是一个初学者,应该避免依赖注入,直到更好地掌握更多基本概念,如单例模式 - 正如你所建议的那样。
      • 在您的第一个选项中,您的意思是在每个表单的构造函数中将所有信息作为参数传递吗?有很多属性,在每种形式中都有属性访问器可能是不可取的(i.t.o. 维护)。另一种选择是创建一个具有这些属性的内部静态类,以便我以后使用 - 你对此有何看法?
      • 嗯...感谢您的帮助,但不完全是菜鸟开发人员。我承认,我应该知道的事情就像我的手背一样! :)
      【解决方案3】:

      存储此类信息的正确位置是在 IIdentity 的自定义实现中。您需要识别用户或其访问权限的任何信息都可以存储在该对象中,然后与当前线程相关联,并且可以在需要时从当前线程中查询。

      此主体在 Rocky Lhotka's CLSA books 或 google winforms 自定义标识中说明。

      【讨论】:

        【解决方案4】:

        我不相信这是正确的方法,但你可以做这样的事情(似乎是你想要的):

        public class Sessions
        {
            // Variables
            private static string _Username;
        
            // properties
            public static string Username
            {
                get
                {
                    return _Username;
                }
                set
                {
                    _Username = value;
                }
            }
        }
        

        如果 c# 错误...我是 vb.net 开发人员...

        那么你只需使用 Sessions.USername 等

        【讨论】:

        • 静态属性引入线程问题,应予以解决。
        猜你喜欢
        • 1970-01-01
        • 2019-08-09
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-18
        • 2011-10-19
        • 1970-01-01
        相关资源
        最近更新 更多