C# 全球数据真的那么糟糕吗?

C# 全球数据真的那么糟糕吗?,c#,wpf,mvvm,global-variables,C#,Wpf,Mvvm,Global Variables,我有一个WPF mvvm应用程序来处理装运数据,这包括将其分解为项目和形式表等 然而,我现在面临的是,需要知道在众多的视图模型中,当前选择了哪个项目,哪个形式,等等,以及访问数据列表,例如从数据库中提取的项目 现在,这些数据通过我称为存储库的类进行加载、更新、删除和插入。例如ProjectRepository,我的计划是将加载的数据也存储在这些类中,因此它将包含一个列表(其中project是我的模型),可以公开访问,并且这些存储库是静态的 所以问题归结到这一点,形式表是基于当前选择的项目加载的(

我有一个WPF mvvm应用程序来处理装运数据,这包括将其分解为项目和形式表等

然而,我现在面临的是,需要知道在众多的视图模型中,当前选择了哪个项目,哪个形式,等等,以及访问数据列表,例如从数据库中提取的项目

现在,这些数据通过我称为存储库的类进行加载、更新、删除和插入。例如ProjectRepository,我的计划是将加载的数据也存储在这些类中,因此它将包含一个列表(其中project是我的模型),可以公开访问,并且这些存储库是静态的

所以问题归结到这一点,形式表是基于当前选择的项目加载的(通过数据库中的projectID),因此存储库需要知道选择了哪个项目。我当前的系统使用viewmodels也订阅的自定义事件来捕获项目选择中的更改,但是我现在看到几十个事件,每个事件都有几十个订阅者,这对我来说似乎有点可笑,坦率地说,这使得遵循代码非常困难

所以,很抱歉这篇文章太多了,我想弄清楚我的处境,然后问一个我知道会激怒一些人的问题。有一个静态类只保存当前所选对象(项目、形式表、装运等)的属性,有什么错呢?这会让我的生活变得更加轻松


还是有一种我还没有见过的“正确”的方法来实现这一点?

在每个进程都是一个用户使用的桌面解决方案中,使用带有共享数据的静态类根本没有问题(在许多情况下,这是“正确”的方法),当一个进程用于服务多个用户时,问题就会出现(例如web页面),因为数据将在用户之间混合。

全局状态的问题是,它使您很难为应用程序编写单元测试


解决您的问题的一种更容易测试的方法是使用一个factory类,该类负责为给定的viewmodel构建并返回适当的存储库。

我认为,如果您试图对可变数据使用全局静态对象,它通常指向一个设计缺陷

使用全局变量的中心问题是失去了所有的封装。这意味着,随着应用程序规模的增长,不可能考虑(或测试)作为组件的程序的一部分。每个组件的每个实例都有可能与其他组件进行交互,由全局静态对象介导。一旦将线程和并发添加到混合中,问题就会变得更加复杂

我当前的系统使用viewmodels订阅的自定义事件来捕获项目选择中的更改,但是我现在有几十个事件,每个事件都有几十个订阅者,这对我来说似乎有点可笑,坦率地说,这使得遵循代码非常困难

我不相信这会让你的生活变得更轻松,即使是在短期内。当项目发生变化时,视图模型不需要得到通知吗?否则,它们可能会显示或处理过时的数据。我觉得这听起来(承认是基于有限的信息)您应该尝试简化用户更改项目时发生的事件链


也许你可以扔掉视图并重新创建它们?或者在基本视图模型中添加一个虚拟方法,如“OnProjectChanged”?或者,如果视图模型实际上不需要得到更改通知,只需向它们传递一个
Func
,以便它们可以在需要时懒洋洋地提取当前数据。我不知道什么是最好的,但必须有一个比引入全局静态和承担所有这些带来的麻烦更好的解决方案。

啊,对不起,我应该这样做如前所述,这只是一个桌面应用程序。是的,我想是的,我只是用这句话来澄清什么时候使用静态数据是一个坏主意。否决票似乎有点过头了?我一直在问。就像“嘿,VMA,这是VMB。你的XYZ属性的当前值是多少?”“Foo。”“好的,当你Foo I Bar().Kthxbai!”当然,VMA需要引用VMB,但由于它们根据逻辑的需要相互交互,这有什么不好?这实际上是我从未想过要做的事情。我想这种方法似乎没有什么错,除了一些VM需要引用多个其他VM,这可能会变得混乱。