在静态类中存储全局不可变数据

本文关键字:不可变 数据 全局 存储 静态类 | 更新日期: 2023-09-27 18:09:32

我有一个WinForms项目,它使用了很多用户控件。其中一些用户控件使用来自业务逻辑层的类。这些类主要执行对数据库的CRUD操作(通过数据访问层)以及一些额外的验证和报告。

项目使用一些常见的对象(日志用户,一些控制器和验证器),它们在主形式中被实例化,然后通过初始化方法或公共属性注入子用户控件。这意味着,我有很多代码,这些代码只是将这些常见对象从父控件传递给子控件。

为了避免这种情况,我可以创建一个静态类(例如ApplicationContext)并将所有常用控件保存到其中。这将在主表单中发生,并且项目中的所有其他用户控件或表单都可以使用它。

我发现通常不鼓励使用这种模式(在静态类中存储一些全局数据)。但如果这些数据是不可变的呢?这种方法是个好主意吗?

或者你知道任何其他方法,可以帮助我摆脱所有的初始化代码?

在静态类中存储全局不可变数据

你可以使用像Unity或Autofac这样的反转控制容器,让它自动为你连接对象图。

您可以让需要任何一个公共对象的每个对象定义对其接口的依赖,或者通过构造函数参数,或者作为公共属性,并且IoC容器将适当的对象连接在一起。

属性注入示例:

public class MyUserControl : UserControl 
{
    [Dependency]
    public LoggedUserService UserService { get; set; }
    public void Method()
    {
        // the IoC container will ensure that the UserService
        // property has been set to an object
    }
}

在主表单中所做的就是注册您希望IoC容器知道的公共对象,然后请求根对象。对象图将神奇地为您组装,您不必编写所有的连接代码,也不必关心如何完成。

可以使用依赖注入/ioc容器来维护全局对象。我对autofac库有很好的体验,但还有许多其他可用的。当使用setter注入时,你的所有控件都会自动获得set依赖对象。

您将希望在这种情况下使用singleton。单例允许你使用对象的同一个实例,比静态更安全、更灵活。

public sealed class Singleton
{
    public object Property1 {get;set;}
    public void Method1 (){}
    static Singleton instance = null;
    static readonly object padlock = new object();
    Singleton()
    {
    }
    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance==null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }        
}

那么你可以像使用static一样使用它,但是有点不同…

public class Main
{
     public Main()
     {
         Singleton.Instance.Property1 = "somevalue";
         Singleton.Instance.Method1();
     }
}

您可以使用静态类来存储一些不可变的数据—这没有问题。然而,如果你想在那里存储控件,它可能不会像预期的那样工作。例如OnDataBinding和Render。